Sztuka z tekstu: Wyświetlanie obrazów w postaci tekstu

Opublikowane:

30.04.2021

Jeśli chcemy wyświetlić obraz w terminalu lub czystym HTML-u, pomóc nam w tym mogą różne narzędzia do konwersji.

Jeśli chcemy wyświetlić obraz w terminalu lub czystym HTML-u, pomóc nam w tym mogą różne narzędzia do konwersji.

Autor: Frank Hofmann i Axel Beckert

Dzięki coraz bardziej zaawansowanej technologii wyświetlanie na ekranie obrazów o wysokiej rozdzielczości nie jest już trudnym zadaniem. Jednak te coraz bardziej szczegółowe obrazy (w połączeniu z większym rozmiarem, rozdzielczością i głębią kolorów) mają swą cenę, gdyż potrzebują więcej przestrzeni i dłużej się pobierają ze zdalnych źródeł, takich jak przeglądarki i kamerki internetowe.

Czasami chcemy po prostu, aby obraz szybko się załadował. Czas i transfer możemy oszczędzić, wyświetlając obrazy w mniejszej rozdzielczości i głębi kolorów w postaci tekstu (znaki ASCII lub Unicode), bezpośrednio w terminalu i konwertując je w standardzie kolorów ANSI (American National Standards) [1]. Możemy też konwertować obrazy do czystego HTML-a i CSS-a, aby zagnieżdżać wyniki na stronach. Niektóre przeglądarki tekstowe, takie jak ELinks, wyświetlą takie obrazy bezpośrednio na stronie. Na podobnej zasadzie przeglądarka Browsh [2] wykonuje tę pracę wewnętrznie i wyświetla obrazy tekstowo.

W tym artykule omówimy dostępne narzędzia służące do konwertowania obrazów na tekst i weryfikacji, czy takie podejście jest odpowiednie do codziennego użytku. Tekst ten to kontynuacja wcześniejszego artykułu [3], który opisywał narzędzia do tworzenia obrazów ASCII.

Konwersja

Po pierwsze, zanim go zagnieździmy lub wyświetlimy, musimy skonwertować obraz na znaki. W tym celu każdy piksel (lub grupa pikseli) przydzielany jest do odpowiednio pokolorowanej pojedynczej litery lub, bardziej precyzyjnie, do glifu (symbolu graficznego).

Rysunek 1: Fragment pliku tux.txt pokazujący wycinek pingwina Tux w formie sekwencji sterujących ANSI.

Tabela 1: Opcje img2txt

Opcja

Opis

ansi

ANSI z kodami kolorów

bbfr

BBCode [6]

caca

Wewnętrzny format Libcaca

html

HTML ze wsparciem dla CSS i DIV

html3

HTML z tabelami

irc

IRC z kodami kontrolnymi CTRL+K

ps

PostScript

vg

SVG (Scalable Vector Graphics)

tga

Format obrazów Targa

utf8

UTF-8 z powrotem karetki

utf8cr

UTF-8 z powrotem karetki i znakiem końca linii

Konwersję wykonujemy poprzez filtry występujące w odpowiednich bibliotekach. Przykładowo możemy skorzystać z narzędzi aview i asciiview z Ascii Art Library (Aalib) [4] lub img2txt i cacaview z Colour Ascii Art Library (Libcaca) [5]. Wynik końcowy to obraz utworzony za pomocą liter z sekwencjami sterującymi ANSI. W efekcie, dzięki redukcji rozdzielczości i głębi kolorów, zmniejszamy rozmiar obiektu, a obraz może być teraz wyświetlany w terminalu lub przeglądarce tekstowej.

Jako przykład możemy skonwertować na znaki obraz PNG z pingwinem Tux. Skorzystamy z img2txt z Libcaca (program zastąpił imgtoppm z poprzedniej publikacji biblioteki). Aby utworzyć plik tekstowy tux.txt, korzystamy z następującego polecenia:

Opcja

Opis

ansi

ANSI z kodami kolorów

bbfr

BBCode [6]

caca

Wewnętrzny format Libcaca

html

HTML ze wsparciem dla CSS i DIV

html3

HTML z tabelami

irc

IRC z kodami kontrolnymi CTRL+K

ps

PostScript

vg

SVG (Scalable Vector Graphics)

tga

Format obrazów Targa

utf8

UTF-8 z powrotem karetki

utf8cr

UTF-8 z powrotem karetki i znakiem końca linii

$ img2txt tux.png > tux.txt

Rysunek 1 pokazuje fragment zawartości pliku tux.txt. Bez dodatkowych opcji wynikowy tekst ma szerokość 60 znaków i format kolorowego ANSI.

Dzięki opcji -W (-width) możemy zmienić szerokość wyjścia. Jeśli nie podamy wysokości za pomocą -H (-height), img2txt przeskaluje tę wartość, tak aby odpowiadała proporcjom oryginalnego obrazu. Opcja -f (--format) pozwala zdefiniować format wyjścia. Tabela 1 podsumowuje opcje img2txt.

Jeśli chcemy zapisać obrazy ANSI z powrotem jako normalne obrazy, możemy skorzystać z biblioteki AnsiLove [7]. Przetwarzając kody ANSI, AnsiLove tworzy zrzuty ekranu w formacie PNG, przez co nie musimy sami tworzyć zrzutów ekranu w terminalu.

Wyświetlanie skonwertowanych obrazów

Już od jakiegoś czasu eksperymentowaliśmy z narzędziami wyświetlającymi skonwertowane obrazy. Wiosną 2020 roku wśród narzędzi Axela [8] znajdowały się chafa [9] i aha [10] oraz catimg [11]. Chociaż ostatnia nazwa zdecydowanie odnosi się do poleceń cat/tac, to catimg może sugerować, że to narzędzie do wyświetlania obrazów kotów (cat po angielsku to kot). Na szczęście potrafi zdecydowanie więcej. Podczas naszych testów na scenie pojawił się też program jp2a [12] działający podobnie do img2txt.


Rysunek 2: Pingwin Tux jako obraz tekstowy, pokazany za pomocą chafa.


Działające w roli przeglądarek obrazów w terminalach chafa i catimg są integralną częścią stabilnych wydań dystrybucji Linuksa od Debiana GNU/Linux 10. chafa wyświetla, bez przycinania, jeden lub więcej obrazów w postaci pokazu slajdów (Rysunek 2). Dostosowuje rozmiar obrazu do aktualnej szerokości i wysokości okna terminala. Z drugiej strony catimg układa obraz w oparciu na jego szerokość, przez co górna jego krawędź znika w czasie przewijania na granicy okna. Następujące dwa wywołania korzystają z chafa do wyświetlenia pojedynczego obrazu i pokazu slajdów wszystkich plików PNG w aktualnym katalogu.

$ chafa linux.png

$ chafa *.png

chafa posiada kilka interesujących opcji włączających różne efekty. Przykładowo możemy dodać -c (--colors), aby ustawić liczbę kolorów (2, 16, 256) lub tryb 24-bitowy. Opcja -d (--duration) określa, jak długo obraz pozostaje widoczny na pokazie slajdów (domyślnie trzy sekundy). Rozmiar obrazu możemy zdefiniować przez -s (--size)x. Domyślnie, chafa, jeśli nie może określić rozmiaru, korzysta z terminala o wymiarach 80 × 25 znaków. Opcja --watch wyświetla obraz ponownie, po każdej zmianie. W przypadku catimg możemy wybrać opcję -l do kontrolowania tego, ile razy odtworzy animowany GIF.

chafa i catimg nie obsługują efektów przejścia, które uatrakcyjniłyby pokaz slajdów. Być może twórcy przeczytają ten artykuł i rozważą dodanie takiej funkcji w przyszłości.

Różnice

Prezentowane w tym artykule narzędzia są bardzo podobne, ale mają też sporo różnic. Przykładowo aview potrafi tylko obsługiwać obrazy w formacie PNM i wyświetla je w skali szarości, gdyż Aalib nie wspiera kolorów. Narzędzie asciiview z Aalib działa jako podstawa aview, konwertująca obrazy do formatu PNM wymaganego przez aview z góry, kiedy korzysta z zewnętrznych narzędzi. Animowane GIF-y nie działają.

Jeśli przy wywołaniu nie określimy tego inaczej, img2txt konwertuje obrazy do ASCII zamiast glifów Unicode i korzysta tylko z 16 kolorów. W zależności od terminala niektóre znaki mogą migotać. Podobnie jak w img2txt, cacaview to prosta przeglądarka obrazów, otwierająca osobne okno, aby wykorzystać najlepsze możliwe ustawienia terminala. W rezultacie nic tu nie miga. Jednak animowane GIF-y też nie działają.

Zarówno chafa, jak i catimg wyświetlają pliki PNG, JPEG, GIF, jak też wiele innych formatów obrazów w więcej niż 16 kolorach. Jeśli terminal to umożliwia, oba programy korzystają z glifów Unicode. Oba też obsługują GIF-y. Przy wyświetlaniu animowanych GIF-ów programy te prezentują je w nieskończonej pętli i nie kończą działania samemu.

Ponieważ catimg zawsze korzysta z całej szerokości terminala, możemy dodać opcję -w, aby określić szerokość wyświetlanego obrazu, jeśli tego potrzebujemy. Rysunek 3 pokazuje zastosowanie szerokości 100 pikseli.


Rysunek 3: Obraz tekstowy Linusa Torvaldsa ograniczony do szerokości 100 pikseli w catimg.


Rysunek 4: Tux jako obraz tekstowy na stronie internetowej.


Rysunek 5: Wynik działania polecenia jako obraz w przeglądarce internetowej.




Listing 1: Dodanie obrazu do kodu HTML

<img src="tux.png" alt="Tux, linuksowy pingwin">

Listing 1: Dodanie obrazu do kodu HTML

Listing 2: HTML i Aha

$ ls --color=always | aha --pink > ls.html

Listing 2: HTML i Aha

W sieci

Jeśli znacie język HTML, z pewnością widzieliście znacznik <img>. Kod z Listingu 1 odnosi się do pliku graficznego tux.png i zagnieżdża go do wyświetlenia w aktualnej lokalizacji na stronie.

Atrybut alt (od 2011 roku jest obowiązkowy) określa tekst wyświetlany przez przeglądarkę, jeśli nie może (lub nie powinna) załadować obrazu. Na przykład jeśli przeglądamy stronę programem ją odczytującym, takim jak Orca [13], odczyta on właśnie ten tekst.

aha, będący adapterem ANSI HTML, oraz img2txt i jp2a (poprzez dodanie odpowiednich opcji) konwertują tekst z kodami kolorów ANSI (lub obrazy) na tekstowe sekwencje i znaczniki HTML-a, aby dodać kolor. Po takiej operacji możemy skopiować wynik ich działania bezpośrednio do pliku HTML (Rysunek 4).

Dlaczego mielibyśmy chcieć korzystać z obrazów tekstowych na stronie? Możemy dodać zawartość terminala jako zrzut ekranu, bez potrzeby korzystania z obrazów, oszczędzając przy tym na wielkości strony, gdyż taki zrzut ekranu jest mniej więcej w oryginalnym formacie, czyli tekście.

Rysunek 5 pokazuje listę plików w katalogu ze specjalnym, różowym tłem. Korzystając z sekwencji poleceń z Listingu 2, przekazujemy wynik działania polecenia ls do aha, który nadaje różowe tło i zapisuje wynik w pliku ls.html.

Teoretycznie, takie dane mogą być odczytane przez program czytający ekran. Jednak w naszych testach działało to dobrze tylko przy obrazach w czerni i bieli. Prawdopodobnie kontrast nie jest wystarczający, jeśli program ma do czynienia z innymi kolorami.

Wideo

Technikę tę możemy też zastosować do plików wideo. Aby to zrobić, korzystamy z bibliotek AAlib i Libcaca w roli wtyczek do Mplayera i VLC (obie), Xine (AAlib) i Mpv [14] (Libcaca). Z kolei projekt Hasciicam [15] tworzy obrazy ASCII, kiedy źródłem jest karta TV lub kamera.

Odtwarzacz Mpv posiada też własny format, TCT (True Color Text). Jednak dokumentacja TCT jest dosyć uboga, gdyż jest on tylko wspomniany na stronie pomocy Mpv (samo znaczenie skrótu TCT byliśmy w stanie określić tylko dzięki komentarzom w kodzie źródłowym). Przydałoby się więcej informacji na ten temat.

Tabela 2 przedstawia przykładowe polecenia do odtwarzania sekwencji filmowych. Rysunek 6 pokazuje efekt działania aaxine.

Tabela 2: Konwertowanie wideo za pomocą AAlib i Libcaca

Program

Przykładowe polecenie

Mpv z biblioteką TCT

mpv --vo=tct https://youtu.be/Qd_1t7kw5EA

Mpv z Libcaca

mpv --vo=caca https://youtu.be/Qd_1t7kw5EA

MPlayer z AAlib

mplayer -vo aa wideo.mp4

Xine z AAlib

aaxine wideo.mp4

Rysunek 6: Wykorzystanie aaxine do odtworzenia wideo.

Rysunek 7: Ciąg znaków foobar w formie testowej kodu QR.

Program

Przykładowe polecenie

Mpv z biblioteką TCT

mpv --vo=tct https://youtu.be/Qd_1t7kw5EA

Mpv z Libcaca

mpv --vo=caca https://youtu.be/Qd_1t7kw5EA

MPlayer z AAlib

mplayer -vo aa wideo.mp4

Xine z AAlib

aaxine wideo.mp4

Działa to bardzo dobrze, ale osiąga swoje granice, kiedy na przykład musimy obejrzeć nagraną prezentację. Jeśli slajdy są zagnieżdżone w nagraniu z prezentacji, tekst na nich jest często nieczytelny. Aby go odczytać, potrzebowalibyśmy funkcji OCR oraz możliwości zmiany rozdzielczości i konwersji na inny format.

Kody QR

To, co pracuje z obrazami i materiałami wideo, działa też z kodami QR. Upraszczając, kody QR to w sumie specjalne obrazy, które mogą być wyświetlane w wierszu poleceń. Zaletą w tym wypadku jest to, że nie musimy tworzyć „pikseli” kodu QR jako glifów. Wystarczy skonwertować każdy blok na pusty, na wpół wypełniony lub pełny znak Unicode.

Oznacza to, że kody QR wyglądają w terminalu dokładnie tak samo jak postaci rzeczywistego obrazu. To samo odnosi się do reprezentacji tekstowej na stronach. Przydatne narzędzia to w tym wypadku qrencode [16] i qrcode [17] z pakietu go-qrcode pod Debianem. Rysunek 7 pokazuje ciąg znaków foobar w formie kodu QR zapisanego tekstowo.

Zastosowanie tej funkcji pokazuje wtyczka pass-otp do jednorazowych haseł, w menedżerze haseł pass [19]. Za pomocą qrencode i qrcode informacje otrzymywane za pomocą kodów QR mogą też być przekazywane w tej formie – nawet w terminalu.

Wnioski

Możemy jeszcze zasugerować kilka ciekawych aplikacji. Warto sprawdzić asciinema [20], MapSCII [21] i ASCIIQuarium [22].

Za pomocą asciinema możemy zapisywać sesję w terminalu w postaci wideo. Dodatkowo strona projektu zastępuje YouTube’a, gdyż zachowuje nasze nagrania w 8-bitach. MapSCII (Rysunek 8), cyfrowy atlas oparty na OpenStreetMap posiada funkcję zbliżenia mapy (Rysunek 8). Za pomocą A przybliżamy widok, Z go oddala, a strzałki kursora pozwalają przesuwać mapę. Współrzędne środka obrazu, widoczne na dole ekranu, pomagają w orientacji.


Rysunek 8: MapSCII to oparty na ASCII cyfrowy atlas z funkcją przybliżania.


Rysunek 9: ASCIIQuarium umieszcza w naszym terminalu różne wodne gatunki.

Jeśli potrzebujemy chwili relaksu, warto uruchomić ASCIIQuarium (Rysunek 9), program zmieniający terminal w wirtualne akwarium. Udanego połowu!



Info

[1] Sekwencje ucieczki: https://www.nayab.xyz/linux/escapecodes.html

[2] Tim Schürmann „Call web pages in the terminal with Browsh”, ADMIN Magazine, nr 53, 2019, https://www.admin-magazine.com/Archive/2019/53/Call-web-pages-in-the-terminal-with-Browsh

[3] Frank Hofmann i Thomas Winde „Creating artistic images with ASCII art”, Linux Magazine, https://www.linux-magazine.com/Issues/2014/168/ASCII-Art/(language)/eng-US

[4] AAlib: http://aa-project.sourceforge.net/aalib/

[5] Libcaca: http://caca.zoy.org/wiki/libcaca

[6] BBCode: https://pl.wikipedia.org/wiki/BBCode

[7] AnsiLove: https://www.ansilove.org/

[8] Axel Beckert „Pictures in pure HTML with chafa and aha”: http://noone.org/blog/English/Computer/Pictures%20in%20pure%20HTML%20with%20chafa%20and%20aha.futile

[9] chafa: https://hpjansson.org/chafa/

[10] aha: https://github.com/theZiz/aha

[11] catimg: https://github.com/posva/catimg

[12] jp2a: https://github.com/cslarsen/jp2a

[13] Orca: https://help.gnome.org/users/orca/stable/

[14] Mpv: https://mpv.io

[15] Hasciicam: http://ascii.dyne.org

[16] qrencode: https://fukuchi.org/works/qrencode/

[17] qrcode: https://github.com/skip2/go-qrcode

[18] pass-otp: https://github.com/tadfisher/pass-otp

[19] pass: https://www.passwordstore.org/

[20] asciinema: https://asciinema.org/

[21] MapSCII: https://mapscii.me/

[22] ASCIIQuarium: https://robobunny.com/projects/asciiquarium/html/

Autorzy: Frank Hofmann pracuje głównie w trasie, jako deweloper, szkoleniowiec i autor. Jego ulubione miejsca pracy to Berlin, Genewa i Kapsztad. Axel Beckert to administrator systemu Linux i specjalista od bezpieczeństwa sieci w departamencie IT w ETH Zurich. Związany też jest z Debianem, LUGS (Linux User Group Switzerland), podkastami Hackerfunk i różnymi otwartymi projektami. Hofmann i Beckert są autorami Debian Package Management.

Aktualnie przeglądasz

Maj 2021 - Nr 207
LM207_May-2021

Top 5 czytanych

Znajdź nas na Facebook'u

Opinie naszych czytelników

Nagrody i wyróżnienia