Prohlížeč obrázků v terminálu

Založil Roman Horník, 14. 01. 2014, 23:37:03

Předchozí téma - Další téma

Roman Horník

Terminál, přesněji řečeno emulátor terminálu, jistě všichni znáte. Víte nejspíš, že umí barvy, ale kdo z vás ví, že jich neumí jen 16, ale rovnou 256? Ale přesto, že má "tolik" barev (Xka vám jich nabízej 16777216, z toho 256 odstínů šedi), neumí grafiku, jen text. A když už se naskytne nějakej "prohlížeč obrázků" pro terminál, vypadá to dost blbě, protože se obrázek zobrazuje pomocí ASCII znaků, což sice obrázek připomíná, ale vypadá to zblízka jako písmenková polívka. A nehledě na to, že tohle bylo dělaný jen pro určitej typ písma s určitou velikostí, takže při změně fontu maj znaky jinej jas, než autor prohlížeče požadoval, takže to vypadá ještě hůř, než se čekalo.
Ale my jsme na to šli jinak. Napsal jsem takovou malou demonstraci toho, že i terminál může zobrazovat grafiku docela na úrovni. Je to sice pomalý, černobílý, rozlišení je závislý na velikosti okna terminálu a rozměrech znaku, ale podporuje to spoustu grafickejch formátů, výstup se dá uložit pro pozdější mnohem rychlejší zobrazení, dá se použít pro slideshow a umí to až 153 odstínů šedi. Pro použití je potřeba akorát doinstalovat ImageMagick.

Program se skládá ze 2 částí, z konvertoru a konvertoru-zobrazovače.
Nejdřív se obrázek upraví pomocí ImageMagick na požadovaný rozměry, v případě potřeby se přidaj kvůli centrování okraje a uloží do nekomprimovanýho formátu PGM. To je krásně čitelnej formát pro černobílou bimapovou grafiku, kde každej pixel je reprezentován numerickou hodnotou, tady v intervalu 0-255 (černá-bílá).
Následuje konvertor-zobrazovač, kterej čte data z onoho PGM obrázku, hodnoty decimuje na až 153 úrovní z až 256 úrovní na vstupu, ke každý z nich přidá barvu pomocí escape sekvence, výsledek se pak zobrazí. Terminál umí bezpečně 26 úrovní šedi (+ další 2, který se ovšem zobrazujou v různých terminálech jinak) na popředí i na pozadí, zbytek se míchá rozdílnou barvou popředí i pozadí, za použití trojice zvláštních znaků: ▓ (75%popředí, 25% pozadí), ▒ (50% popředí, 50% pozadí) a ░ (25% popředí, 75% pozadí). Byly nově přidány i 2 dodatkový znaky z Braillova písma pro eliminaci ostrých přechodů.

Takhle to vypadá:

To velký je Xterm, to malý terminál. Kliknutím na obrázek se načte v plný velikosti.

... a tady je kód (aktualizováno):

#!/bin/bash
O="/tmp/tmp.pgm"
R=`tput cols`x`tput lines`

## Jestli to není obrázek, nebo jestli soubor neexistuje, tak se ukonči
if [ ! -f $1 ]
then exit
elif grep -q image <<<`file $1`
then

## Schová kurzor
echo -ne "\e[?25l"

## Pro zrychlení: zmenší/zvětší obrázek podle jeho rozměrů tak, aby se velký obrázky
## zpracovávaly rychlejc, ale aby malý obrázky pokud možno neutrpěly ztrátu detailů
## U je relativní k vejšce znaku, V zase k šířce (v tomhle případě 5×8px), W je filtr.
## Je to narychlo a baj vočko udělaná prasečina, ale kupodivu funguje.
PIX=$((`identify $1 | awk '{print $3}' | sed -e 's/x/*(/g;s/$/\/2\)\/500/g'`))
if [ $PIX -le 10 ]
then U=640; V=400; W="sincfast"
  elif [ $PIX -le 100 ]
   then U=320; V=200; W="box"
    elif [ $PIX -le 500 ]
     then U=160; V=100; W="box"
      elif [ $PIX -le 1000 ]
       then U=80; V=50; W="box"
        elif [ $PIX -le 5000 ]
         then U=40; V=25; W="box"
          elif [ $PIX -le 10000 ]
           then U=16; V=10; W="box"
            elif [ $PIX -le 20000 ]
             then U=8; V=5; W="box"
              elif [ $PIX -gt 20000 ]
               then U=4; V=2.5; W="box"
fi

## Nastavení správných rozměrů, konverze do PGM
convert \
-comment img2term \
$1 \
-filter $W \
-resize $U%x$V \
-filter Triangle \
-resize $R \
-gamma 2 \
-background black \
-gravity center \
-extent $R \
-depth 8 \
-compress none \
$O

tput cup 0 0

## Načtení dat z PGM obrázku, přeformátování na takovej počet sloupců, jako má terminál,
## decimace barevný palety, aby se 256 odstínů vešlo do 153 odstínů, vykreslení
echo -ne "$(cat $O | tail -n $((`cat $O | wc -l`-4)) | xargs -n `cat $O | sed -n 3p | awk '{print $1}'` | sed -e '
s/$/ /g;
s/255 /\\e[107m /g;
s/254 /\\e[107;38;5;255m⡈/g;
s/25[23] /\\e[107;38;5;255m⡪/g;
s/25[01] /\\e[107;38;5;255m░/g;
s/24[7-9] /\\e[107;38;5;255m▒/g;
s/24[56] /\\e[107;38;5;255m▓/g;
s/24[34] /\\e[97;48;5;255m⡪/g;
s/24[0-2] /\\e[48;5;255m /g;
s/239 /\\e[48;5;255;38;5;254m⡪/g;
s/23[78] /\\e[48;5;255;38;5;254m░/g;
s/23[56] /\\e[48;5;255;38;5;254m▒/g;
s/23[34] /\\e[48;5;255;38;5;254m▓/g;
s/232 /\\e[38;5;255;48;5;254m⡪/g;
s/23[01] /\\e[48;5;254m /g;
s/229 /\\e[48;5;254;38;5;253m⡪/g;
s/22[78] /\\e[48;5;254;38;5;253m░/g;
s/22[56] /\\e[48;5;254;38;5;253m▒/g;
s/22[34] /\\e[48;5;254;38;5;253m▓/g;
s/222 /\\e[38;5;254;48;5;253m⡪/g;
s/22[01] /\\e[48;5;253m /g;
s/219 /\\e[48;5;253;38;5;252m⡪/g;
s/21[78] /\\e[48;5;253;38;5;252m░/g;
s/21[56] /\\e[48;5;253;38;5;252m▒/g;
s/21[34] /\\e[48;5;253;38;5;252m▓/g;
s/212 /\\e[38;5;253;48;5;252m⡪/g;
s/21[01] /\\e[48;5;252m /g;
s/209 /\\e[48;5;252;38;5;251m⡪/g;
s/20[78] /\\e[48;5;252;38;5;251m░/g;
s/20[56] /\\e[48;5;252;38;5;251m▒/g;
s/20[34] /\\e[48;5;252;38;5;251m▓/g;
s/202 /\\e[38;5;252;48;5;251m⡪/g;
s/20[01] /\\e[48;5;251m /g;
s/199 /\\e[48;5;251;38;5;250m⡪/g;
s/19[78] /\\e[48;5;251;38;5;250m░/g;
s/19[56] /\\e[48;5;251;38;5;250m▒/g;
s/19[34] /\\e[48;5;251;38;5;250m▓/g;
s/192 /\\e[38;5;251;48;5;250m⡪/g;
s/19[01] /\\e[48;5;250m /g;
s/189 /\\e[48;5;250;38;5;249m⡪/g;
s/18[78] /\\e[48;5;250;38;5;249m░/g;
s/18[56] /\\e[48;5;250;38;5;249m▒/g;
s/18[34] /\\e[48;5;250;38;5;249m▓/g;
s/182 /\\e[38;5;250;48;5;249m⡪/g;
s/18[01] /\\e[48;5;249m /g;
s/179 /\\e[48;5;249;38;5;248m⡪/g;
s/17[78] /\\e[48;5;249;38;5;248m░/g;
s/17[56] /\\e[48;5;249;38;5;248m▒/g;
s/17[34] /\\e[48;5;249;38;5;248m▓/g;
s/172 /\\e[38;5;249;48;5;248m⡪/g;
s/17[01] /\\e[48;5;248m /g;
s/169 /\\e[48;5;248;38;5;247m⡪/g;
s/16[78] /\\e[48;5;248;38;5;247m░/g;
s/16[56] /\\e[48;5;248;38;5;247m▒/g;
s/16[34] /\\e[48;5;248;38;5;247m▓/g;
s/162 /\\e[38;5;248;48;5;247m⡪/g;
s/16[01] /\\e[48;5;247m /g;
s/159 /\\e[48;5;247;38;5;246m⡪/g;
s/15[78] /\\e[48;5;247;38;5;246m░/g;
s/15[56] /\\e[48;5;247;38;5;246m▒/g;
s/15[34] /\\e[48;5;247;38;5;246m▓/g;
s/152 /\\e[38;5;247;48;5;246m⡪/g;
s/15[01] /\\e[48;5;246m /g;
s/149 /\\e[48;5;246;38;5;245m⡪/g;
s/14[78] /\\e[48;5;246;38;5;245m░/g;
s/14[56] /\\e[48;5;246;38;5;245m▒/g;
s/14[34] /\\e[48;5;246;38;5;245m▓/g;
s/142 /\\e[38;5;246;48;5;245m⡪/g;
s/14[01] /\\e[48;5;245m /g;
s/139 /\\e[48;5;245;38;5;244m⡪/g;
s/13[78] /\\e[48;5;245;38;5;244m░/g;
s/13[56] /\\e[48;5;245;38;5;244m▒/g;
s/13[34] /\\e[48;5;245;38;5;244m▓/g;
s/132 /\\e[38;5;245;48;5;244m⡪/g;
s/13[01] /\\e[48;5;244m /g;
s/129 /\\e[48;5;244;38;5;243m⡪/g;
s/12[78] /\\e[48;5;244;38;5;243m░/g;
s/12[56] /\\e[48;5;244;38;5;243m▒/g;
s/12[34] /\\e[48;5;244;38;5;243m▓/g;
s/122 /\\e[38;5;244;48;5;243m⡪/g;
s/12[01] /\\e[48;5;243m /g;
s/119 /\\e[48;5;243;38;5;242m⡪/g;
s/11[78] /\\e[48;5;243;38;5;242m░/g;
s/11[56] /\\e[48;5;243;38;5;242m▒/g;
s/11[34] /\\e[48;5;243;38;5;242m▓/g;
s/112 /\\e[38;5;243;48;5;242m⡪/g;
s/11[01] /\\e[48;5;242m /g;
s/109 /\\e[48;5;242;38;5;241m⡪/g;
s/10[78] /\\e[48;5;242;38;5;241m░/g;
s/10[56] /\\e[48;5;242;38;5;241m▒/g;
s/10[34] /\\e[48;5;242;38;5;241m▓/g;
s/102 /\\e[38;5;242;48;5;241m⡪/g;
s/10[01] /\\e[48;5;241m /g;
s/99 /\\e[48;5;241;38;5;240m⡪/g;
s/9[78] /\\e[48;5;241;38;5;240m░/g;
s/9[56] /\\e[48;5;241;38;5;240m▒/g;
s/9[34] /\\e[48;5;241;38;5;240m▓/g;
s/92 /\\e[38;5;241;48;5;240m⡪/g;
s/9[01] /\\e[48;5;240m /g;
s/89 /\\e[48;5;240;38;5;239m⡪/g;
s/8[78] /\\e[48;5;240;38;5;239m░/g;
s/8[56] /\\e[48;5;240;38;5;239m▒/g;
s/8[34] /\\e[48;5;240;38;5;239m▓/g;
s/82 /\\e[38;5;240;48;5;239m⡪/g;
s/8[01] /\\e[48;5;239m /g;
s/79 /\\e[48;5;239;38;5;238m⡪/g;
s/7[78] /\\e[48;5;239;38;5;238m░/g;
s/7[56] /\\e[48;5;239;38;5;238m▒/g;
s/7[34] /\\e[48;5;239;38;5;238m▓/g;
s/72 /\\e[38;5;239;48;5;238m⡪/g;
s/7[01] /\\e[48;5;238m /g;
s/69 /\\e[48;5;238;38;5;237m⡪/g;
s/6[78] /\\e[48;5;238;38;5;237m░/g;
s/6[56] /\\e[48;5;238;38;5;237m▒/g;
s/6[34] /\\e[48;5;238;38;5;237m▓/g;
s/62 /\\e[38;5;238;48;5;237m⡪/g;
s/6[01] /\\e[48;5;237m /g;
s/59 /\\e[48;5;237;38;5;236m⡪/g;
s/5[78] /\\e[48;5;237;38;5;236m░/g;
s/5[56] /\\e[48;5;237;38;5;236m▒/g;
s/5[34] /\\e[48;5;237;38;5;236m▓/g;
s/52 /\\e[38;5;237;48;5;236m⡪/g;
s/5[01] /\\e[48;5;236m /g;
s/49 /\\e[48;5;236;38;5;235m⡪/g;
s/4[78] /\\e[48;5;236;38;5;235m░/g;
s/4[56] /\\e[48;5;236;38;5;235m▒/g;
s/4[34] /\\e[48;5;236;38;5;235m▓/g;
s/42 /\\e[38;5;236;48;5;235m⡪/g;
s/4[0-1] /\\e[48;5;235m /g;
s/39 /\\e[48;5;235;38;5;234m⡪/g;
s/3[78] /\\e[48;5;235;38;5;234m░/g;
s/3[56] /\\e[48;5;235;38;5;234m▒/g;
s/3[34] /\\e[48;5;235;38;5;234m▓/g;
s/32 /\\e[38;5;235;48;5;234m⡪/g;
s/3[01] /\\e[48;5;234m /g;
s/29 /\\e[48;5;234;38;5;233m⡪/g;
s/2[78] /\\e[48;5;234;38;5;233m░/g;
s/2[56] /\\e[48;5;234;38;5;233m▒/g;
s/2[34] /\\e[48;5;234;38;5;233m▓/g;
s/22 /\\e[38;5;234;48;5;233m⡪/g;
s/2[01] /\\e[48;5;233m /g;
s/19 /\\e[48;5;233;38;5;232m⡪/g;
s/1[78] /\\e[48;5;233;38;5;232m░/g;
s/1[56] /\\e[48;5;233;38;5;232m▒/g;
s/1[34] /\\e[48;5;233;38;5;232m▓/g;
s/12 /\\e[38;5;233;48;5;232m⡪/g;
s/1[01] /\\e[48;5;232m /g;
s/9 /\\e[48;5;232;38;5;0m⡪/g;
s/[78] /\\e[48;5;232;30m░/g;
s/[56] /\\e[48;5;232;30m▒/g;
s/[34] /\\e[48;5;232;30m▓/g;
s/2 /\\e[38;5;232;40m⡪/g;
s/1 /\\e[38;5;232;40m⡈/g;
s/0 /\\e[40m /g')\e[00m"
tput cup `tput lines` 0

## Informace o obrázku vlevo dole
echo -ne "\e[38;5;228;48;5;22m `identify $1|awk '{print $1, "\e[38;5;22;48;5;228m", $3, "\b,", $7}'` \e[00m"

tput cup `tput lines` `tput cols`
echo -ne "\e[?12l\e[?25h"
else exit
fi
tput cup 0 0


Uložte to do souboru třeba blablabla.sh, nastavte mu spustitelnej příznak (chmod +x soubor) a spusťte /cesta/k/blablabla.sh obrázek.png

Pro spuštění slideshow:
cd /cesta/ke/složce_obrázků/
for X in `ls .`; do /cesta/k/blablabla.sh $X; sleep 5; done


U pomalejších počítačů se může sleep 5; vypustit, ta pětka jinak znamená čekat 5s


P. S.:
*Nefunguje v konzoli. Ta většinou neumí ani použitý escape sekvence, natož 256 barev.
*Lepší použít jako terminál Xterm- má rychlejší vykreslování a dá se dát do plnýho fullscreenu, aniž by tam vadilo menu
*Výstup se dá přesměrovat do souboru, kterej  se dá potom zobrazit třeba pomocí cat. Např. blablabla.sh obrázek.jpg > obrázek.txt, pro zobrazení pak cat obrázek.txt. Bacha ale na velikost okna!
Debian Sid/Experimental 64bit + Mate Desktop Environment
* CPU: Intel i5 3570
* GPU: NVIDIA GTX650 1GD5
* MB: Lenovo IH61M
* RAM: 16GiB Deutsche Demokratische Republik 3 @ 1600MHz

Matesax

#1
Co to tu rozjíždíš za hovna? Grafika vůbec nesouvisí s místem, odkud ji používáš. I konzole může mít miliardy barev. Vždyť to spolu nesouvisí - nespojuj vůbec konzoli s černou a bílou - blbost... Nejprve pochop, co je to VGA - jak to celé začalo. Jak se postupně vyvíjelo SVGA, XGA, SXGA, SXGA+ - prostě:
http://cs.wikipedia.org/wiki/Soubor:Video_Standards.svg

No a aby se tohle nemuselo řešit, připsalo se pod vytyčenou částí RAM pro BIOS - část CMOS Battery - extended BIOS data - ve vyšší paměti - nad řádkem A20 celé jednotné grafické prostředí všech zemí - Super VGA (od QVGA po ...) - VESA... Cílem VESy je zvolení nejlepšího grafického rozhraní - rozlišení, barevná hloubka atd. A proto lze už v BIOSu aplikovat rozšířená data BIOSu - nad 0x4A00 - pro kabel grafiky atd. Ano - mnoho konzolí raději využije staršího RT přístupu - TTY - protože už to dost věcí řeší za programátora. Ale TTY Linuxu je založeno na rozšiřujících driverech. Prostě základem je FrameBuffer a XORG. (XVESA) A tak lze normálně vykreslovat v miliardách barev přímo přes soubor fbdev(2). X POUZE poskytují grafické rozhraní! Není to ovladač, nebo tak... Důkazem jest Mplayer - který používám a X nemám... Obrázky - W3M - parráda... Atd. FrameBuffer je vpodstatě jen zabalená Vesa... A tak lze rastrové obrázky vykreslit jen předáním pixelů... U komrese typu JPEG/PNG je trochu složitější se k pixelům dostat, ale to už je jen vnější nadstavba. Typické BMP obsahuje hlavičku - v ní pointer na první pixel - no a od prvního pixelu to jede jeden za druhým. Vykresluje se od spoda nahoru - Y-- a X zleva doprava normálně - X++... + u nedwordových šířek se aplikuje zarovnání řádku do podoby dělitelné dwordem - 4 byte... Hodnotou zarovnání může být buď 0, nebo filler - který se dá použít třeba pro nadbytečné informace... Zkrátka - grafika NESOUVISÍ s použitým shellem/... Vždy se dá vykreslovat v maximálních možnostech karty... Například v DOSu to dokazuje Arachne - respektive jeho moderní předěl... Používám jej a užívám si plnohodnotné prohlížení webu, editaci obrázků atd...

EDIT:

Vyšší pamětí nemyslím 32bit - ale tu co už není garantována dle IBM - http://wiki.osdev.org/Memory_Map_(x86) Tedy stále ji bez problému obsluhuje prvotní 16 bit režim... A chápu proč si pamětníci DOSu spojují konzoli s omezením barev - dříve to nebylo možné technicky. Ale proč i moderní generace??? Dříve na to nebyl HW - i když už HW něco více uměl, nebyl tak úplně využitelný - ostatně dnes to platí o to více - nevyužije se mnohdy až 30% HW možností... Ale s příslušným HW a využitím Vesy (který šílenec by se snažil udělat vlastní verzi Vesy - kromě mě... :D) má už 40% BIOSů plnohodntnou grafiku - některé i myš. A když už to nevypadá jako Desktop, tak to má loga atp. Čily když už i BIOS se tváří jako Desktop - tak nevidím problém... :D
Nevěřím v nic - pak má víra jest vyšší, než kterákoliv jiná...

Roman Horník

To samozřejmě vím, ale dělal jsem to na stařičkým Optiplexu GX150. PIII @ 1GHz, 512MiB SDRAM @ 133MHz, chipset i815. V čemkoliv jiným, než v Xkách 640×480 se 16 barvama, v Xkách sice až 1600×1200, ale jen se 65536 barvama (=16 bitů). A takovýhle ščoty má ještě hromada lidí, vlastně většina těch, co mi zavolali, abych se jim na počítač "kouknul". Proč taky ne, když jim to stačí a/nebo si prostě novej dovolit nemůžou? Cokoliv jde na tomhle stroji dobře, o to líp pak půjde na strojích novejch. Sice jsem tenhle Optiplex v pondělí dovybavil tím nejlepším, co mi do AGP zůstalo, a sice ATI Rage 128 Pro Ultra TF, což byla ve svý době mocná karta (pro zprovoznění jsem musel ukrást ze Squeezeho z balíku libgl1-mesa-dri knihovničku r128_dri.so, která se od Wheezyho v onom balíku nevyskytuje, bez níž maj GLX kolečka 17FPS namísto současných ~950FPS), ale i když si konečně můžu zvolit rozlišení konzole, furt mám 16 barev- teda jen pomocí ANSI escape sekvencí (\e[xxxm).
Ale tenhle prohlížeč o tom není. Je to jen něco jako ASCII art, ale nepoužívá znaky z ASCII tabulky, nepoužívá pro ně 2-3 odstíny šedi, používá tu černobílou část z 256 barev, který lze pomocí escape sekvencí vyvolat, ale je stejně jako ASCII art omezenej rozměrama znaku. A navíc je to zase jen bashovina, a jak známo, takovej skriptovací jazyk má spoustu omezení. Ale funguje to, dokonce jsem to zrychlil a o trochu zvednul počet odstínů ze 101 na 153 díky znakům Braillovic písma.

P. S.: BMP jsem nezkoumal, ale vím, že se vykresluje opačně, každopádně jsem zvolil PGM, protože nic jednoduššího, než zápis hodnot {0..255}, není (i když by bylo jednodušší a úspornější, kdyby ty hodnoty byly v hexa soustavě, tedy {00..FF})- ta jednoduchost je nutná kvůli použitýmu SEDu.

Jo, dělal jsem to jen jako demonstraci toho, že ten terminál není tak zlej, neschopnej a ošklivej, jak se může na první pohled jevit. Tečka.
Debian Sid/Experimental 64bit + Mate Desktop Environment
* CPU: Intel i5 3570
* GPU: NVIDIA GTX650 1GD5
* MB: Lenovo IH61M
* RAM: 16GiB Deutsche Demokratische Republik 3 @ 1600MHz

Matesax

Nechápu jak mi chceš namluvit že ASCII art ukáže čeho je terminál schopen. Spíše to odradí ještě více lidí... Nevidím problém v tom místo kvalitních formátů používat mobilní, které nebude problém na takovémto PC přehrát přes Mplayer... I na takovémto hrozném PC lze používat HighColors - takže nechápu proč jít úmyslně do horšího...

http://en.wikipedia.org/wiki/List_of_16-bit_computer_hardware_palettes
Nevěřím v nic - pak má víra jest vyšší, než kterákoliv jiná...

Roman Horník

#4
Já zase nechápu, proč opakovaně dáváš všem na odiv svou excelentní natvrdlost. Píšu snad, že to je ASCII Art? Ne, píšu, že to s AA má některý věci společný. Pokud to nevíš, AA využívá pouze tisknutelných znaků tabulky ASCII, na Wikipedii odkazovat nebudu, ale můžeš si v terminálu spustit man ascii, abys viděl, který to jsou. Ale samozřejmě se dá program upravit na AA (bez formátování; je to mnohem rychlejší).
A o schopnostech terminálu - ukaž mi jinej program, co v terminálu dokáže zobrazit obrázek, co má víc jak 153 odstínů šedý (nebo v barvách) rychlostí jen o něco horší, než třeba prohlížeč obrázků EoG, program, co umí ze sekvence obrázků udělat video (viz níže), který se zobrazí přímo v okně terminálu a je koukatelný i na tom starým Optiplexu.
Terminál toho umí samozřejmě víc, barvy bych tam mohl udělat, ale když si ty dostupný barvy prohlídneš, zjistíš, že abys z toho získal rozumnou paletu, musel bys míchat a míchat. Už takhle to byla prdel, a to jsem míchal jen jas. Pak tady máme další 2 rozměry, odstín a sytost. Odstínů je tam poměrně dost, ale co sytost? To by se muselo míchat, to by najednou, aby to za něco stálo, byly při tomhle způsobu míchání zhruba 3 milióny kombinací, každá kombinace by se musela zapsat a ověřovat. A stejně by to ve výsledku bylo k hovnu, protože by to bylo pomalý a žravý. Jas pro dostatečnou interpretaci obrazu stačí, stejně jako stačil přes 100 let u fotek a desítky let u televize. A ještě poměrně nedávno byly ČB počítače, a co teprve mobily? Buďto mi ukážeš něco lepšího, nebo to vytvoříš (pro srovnání nejlíp jako shellovej skript), když máš tak strašně dlouhý zkušenosti, nebo přestaneš pyskovat.

P. S.: Zkoušel jsem předělat na zápis typu \e[48;2;R;G;Bm (kde R|G|B jsou hodnoty 0..255). Hodně se to zjednodušilo, protože jsem nemusel vypisovat každou barvu zvlášť, namísto toho každou hodnotu upravil pomocí awk (např. "147" > "\e[48;2;147;147;147m "), ale jednak to bylo asi stokrát pomalejší, jednak by z toho stejně vylezlo oněch až 256 barev. A taky to uměl jen XTerm, jinde bylo černo. Nepoužitelný.


Ale k věci. Dost jsem na tom zapracoval a program výrazně zdokonalil:
* V první řadě je rychlejší. Odpadla nutnost použít "meziobrázku", výstup z convertu jde rovnou do roury, kde se ihned zpracovává. Oproti předchozí verzi je to zhruba 2x rychlejší
* Odpadla potřeba použít dvou stupňů změny velikosti obrázku, poměr stran je navíc mnohem bližší originálu (záleží ale na "rozlišení" terminálu; malý okno a velký znaky zpravidla budou poměr stran zkreslovat. Dobrý je spouštět prohlížeč v Xtermu, s velikostí písma Tiny (6×10px) a ve fullscreenu
* Dále byl vyřešen problém se soubory s mezerou/mezerami v názvu
* Odpadla potřeba pozicování kurzoru pomocí tput, teď se to děje pomocí escape kódů
* Program umí načíst i vícevrstvý obrázky (GIF, TIFF, XCF,...), ale vzhledem ke způsobu výstupu z IM vždy jen první snímek, nikoliv animace
* Umí to zoomovat, teda jen do středu. Prostě se za příkaz a za cestu k obrázku napíše číslo (v %), takže 50 je poloviční velikost, 200 je dvojnásobná. 100 je výchozí hodnota, nejmenší číslo je 1(%), zadává se celočíselná hodnota (!)
* Pokud se výstup sekvence obrázků přesměrovává do souboru a ten se pak přečte přes cat (v terminálu s nezměněnou velikostí okna), zobrazí se animace. Pokud se onen výstupní soubor komprimuje do tar.gz, má zhruba desetinovou velikost a dá se přečíst přes zcat. Krátký video jsem udělal následovně:
avconv -i video.mp4 -r 20 -f image2 Složka_pro_sekvenci_obrázků/%05d.png #Rozdělení videa na snímky, v tomhle případě se snímkovou frekvencí 20fps
for X in `ls Složka_pro_sekvenci_obrázků`; do ./programek.sh Složka_pro_sekvenci_obrázků/$X >> video.txt; printf "  $X\r"; done #Vytvoření videa ze snímků
cat video.txt #Zobrazení videa
Opakuju, že velikost okna terminálu musí bejt při vytváření videa stejná nebo větší i při přehrávání. Při přehrávání se nedá určit počet zobrazených snímků za vteřinu, záleží na schopnostech stroje a jeho aktuální zátěži jinými procesy.

27. 3. 2014:
* Z programu byly vyňaty zbytečnosti
* Přibyla možnost přiblížit obrázek nejen na střed, ale dá se navíc určit posun od středu. Např. prográmek obrázek.svg 200 -20+20 zajistí dvojnásobný přiblížení s tím, že se onen výřez posune o 20 znaků doleva (-) a 20 znaků dolů (+). Není to zrovna ideální vzhledem k nečtvercovosti znaků, horizontálně se v XTermu u písma Tiny už zmenšenej obrázek posune o 5×20px, vertikálně však o 8×20px. Zadávají se kladný/záporný čísla, ale vždycky s příslušným znamínkem, bez mezery mezi nima.
* Co se tejče přiblížení, teď je možný zadávat čísla jak s desetinnou tečkou, tak i s desetinnou čárkou (protože jsem to tam kopíroval přímo z kalkulačky a nechtěl jsem furt přepisovat čárku tečkou).

TODO: Parametry se budou v budoucnu zadávat pomocí jednoduchých přepínačů, bude možnost nastavit si barvu pozadí, vykreslovací motory (ve skutečnosti jich mám víc, dokonce i pro konzoli) oddělím do samostatných souborů, vytvořím konečně instalační balík a vymyslím tomu jméno.

No a tady je kód:
#!/bin/bash

## Šířka a výška znaku v px
sirka_zn=5
vyska_zn=8

## Přesnost výpočtu pro BC
presn_bc=6

## Česky: Pokud to není soubor (nebo neexistuje), pak tiše zemři,
## jinak pokud je to obrázek, pak konej následující:
if [ ! -f "$1" ]
then exit 66
elif grep -q image <<<`file "$1"`
then

## Získáme počet sloupců a řádků terminálu
poc_sloup=`tput cols`
poc_radku=`tput lines`

## Šířka a výška okna terminálu
sirka_okna=$((poc_sloup*sirka_zn))
vyska_okna=$((poc_radku*vyska_zn))

## Získáme potřebné údaje o obrázku (šířka, výška, formát)
info_obr=`identify -format '%w %h %m' "$1"[0]`

## Z toho se vypreparuje šířka, výška a typ obrázku
sirka_obr=`awk '{print $1}' <<<$info_obr`
vyska_obr=`awk '{print $2}' <<<$info_obr`
typ_obr=`awk '{print $3}' <<<$info_obr`

## Výpočet poměru stran znaku
pom_str_znaku="($sirka_zn/$vyska_zn)"

## Přiblížení. Pokud je uživatelsky zadáno jako 2. parametr
## (1. je vstupní soubor), pak se použije, pokud není, použije se
## výchozí přiblížení, tj. 100%

case "$2" in
"") zoom=100;;
*) zoom=`sed -e 's/,/./' <<<$2`;;
esac

## Tahle věcička vypočítá změnu velikosti a poměru stran obrázku tak, aby při
## úrovni zvětšení 100% právě zaplnil nejdelší rozměr obrázku odpovídající
## strany terminálu. Vzhledem k tomu, že nemají znaky terminálu poměr stran 1:1,
## k obrázkům na výšku přistupuje jinak, než k obrázkům na šířku.
if [ $((sirka_obr*vyska_okna)) -gt $((vyska_obr*sirka_okna)) ]
then vyska_zobr=`bc -l <<<"scale=$presn_bc; $poc_sloup/$sirka_obr*$zoom*$pom_str_znaku"`
else vyska_zobr=`bc -l <<<"scale=$presn_bc; $poc_radku/$vyska_obr*$zoom"`
fi
sirka_zobr=`bc -l <<<"scale=$presn_bc; $vyska_zobr/$pom_str_znaku"`

info="`basename "$1"` \
\e[7m $typ_obr, ${sirka_obr}x${vyska_obr}, \
`du -bh "$1" | awk '{print $1}'`, \
H=`bc -l <<<"scale=2; (0.005+$sirka_zobr)/1"`\045 \
V=`bc -l <<<"scale=2; (0.005+$vyska_zobr)/1"`\045"

## Hlavní motor ########
## Obrázek se zmenší na vypočtené hodnoty $vyska_zobr a $sirka_zobr,
## nastaví se mu černé pozadí (lze změnit) a právě ním se vyplní prázdné místo
## tak, aby rozměr výsledku byl totožný s rozměrem okna terminálu. Obrázek se
## tímto navíc vystředí. Nastaví se osmibitová hloubka (to kdyby se otevíraly
## šestnáctibitové obrázky; IM totiž rád zachovává bitovou hloubku originálu.
## Ale třeba čtyřbitový obrázek motoru nevadí), obrázek se překonvertuje do
## formátu PGM a rourou pošle dál, kde se ořízne hlavička. Protože numerické
## údaje hodnot jednotlivých pixelů IM zpravidla souká do poc_sloupa 20
## sloupců, je potřeba zajistit, aby těch sloupců bylo právě tolik, kolik jich
## má terminál, což spáchá "xargs -n $poc_sloup". Pro větší rychlost lze
## použít jen "xargs". Tato úprava způsobí, že data obrázku budou na jednom
## řádku (nebude jich tolik, kolik jich má terminál, nebude se na konec každého
## řádku strkat \n, xargs bude pracovat rychleji). V tom případě ale nelze
## uložený výstup zobrazit ani ve větším okně terminálu, než ve kterém byl
## vytvořen, neboť se obraz desynchronizuje.
## Pak následuje sed v roli překladače numerických hodnot na escape kódy pro
## popředí i pozadí jednotlivých znaků. Co odstín, to jeden řádek, začíná to
## bílou (255), končí černou (0). A toto celé se pak zobrazí. Pro změnu
## velikosti je použita funkce -scale, kde jako výchozí filtr je použit Box, což
## je rychlý filtr s dostačující kvalitou. Kvalitnější, leč pomalejší škálování
## poskytuje funkce -resize, kde je jako výchozí filtr použit Mitchell nebo
## Lanczos podle toho, jestli obrázek disponuje alfakanálem. Chcete-li použít
## jiný filtr, před touto funkcí definujte žádaný filtr, např.:
## -filter Lagrange -resize $sirka_zobr%x$vyska_zobr
## Seznam filtrů získáte spuštěním příkazu 'convert -list filter' v terminálu.

printf "\e[?25l\e[0;0f$(convert \
-set colorspace RGB -comment "" "$1"[0] \
-scale $sirka_zobr%x$vyska_zobr \
-background black -gravity center -extent ${poc_sloup}x${poc_radku}$3 \
-depth 8 -compress none pgm:- | tail -n+4 | xargs | sed -e '
s/$/ /g;
s/25[45] /\\e[107m /g;
s/25[23] /\\e[107;38;5;255m⡈/g;
s/25[01] /\\e[107;38;5;255m⡪/g;
s/24[89] /\\e[107;38;5;255m░/g;
s/24[67] /\\e[107;38;5;255m▒/g;
s/24[45] /\\e[107;38;5;255m▓/g;
s/24[23] /\\e[97;48;5;255m⡪/g;
s/24[01] /\\e[48;5;255m /g;
s/239 /\\e[48;5;255;38;5;254m⡪/g;
s/23[78] /\\e[48;5;255;38;5;254m░/g;
s/23[56] /\\e[48;5;255;38;5;254m▒/g;
s/23[34] /\\e[48;5;255;38;5;254m▓/g;
s/23[12] /\\e[38;5;255;48;5;254m⡪/g;
s/230 /\\e[48;5;254m /g;
s/229 /\\e[48;5;254;38;5;253m⡪/g;
s/22[78] /\\e[48;5;254;38;5;253m░/g;
s/22[56] /\\e[48;5;254;38;5;253m▒/g;
s/22[34] /\\e[48;5;254;38;5;253m▓/g;
s/22[12] /\\e[38;5;254;48;5;253m⡪/g;
s/220 /\\e[48;5;253m /g;
s/219 /\\e[48;5;253;38;5;252m⡪/g;
s/21[78] /\\e[48;5;253;38;5;252m░/g;
s/21[56] /\\e[48;5;253;38;5;252m▒/g;
s/21[34] /\\e[48;5;253;38;5;252m▓/g;
s/21[12] /\\e[38;5;253;48;5;252m⡪/g;
s/210 /\\e[48;5;252m /g;
s/209 /\\e[48;5;252;38;5;251m⡪/g;
s/20[78] /\\e[48;5;252;38;5;251m░/g;
s/20[56] /\\e[48;5;252;38;5;251m▒/g;
s/20[34] /\\e[48;5;252;38;5;251m▓/g;
s/20[12] /\\e[38;5;252;48;5;251m⡪/g;
s/200 /\\e[48;5;251m /g;
s/199 /\\e[48;5;251;38;5;250m⡪/g;
s/19[78] /\\e[48;5;251;38;5;250m░/g;
s/19[56] /\\e[48;5;251;38;5;250m▒/g;
s/19[34] /\\e[48;5;251;38;5;250m▓/g;
s/19[12] /\\e[38;5;251;48;5;250m⡪/g;
s/190 /\\e[48;5;250m /g;
s/189 /\\e[48;5;250;38;5;249m⡪/g;
s/18[78] /\\e[48;5;250;38;5;249m░/g;
s/18[56] /\\e[48;5;250;38;5;249m▒/g;
s/18[34] /\\e[48;5;250;38;5;249m▓/g;
s/18[12] /\\e[38;5;250;48;5;249m⡪/g;
s/180 /\\e[48;5;249m /g;
s/179 /\\e[48;5;249;38;5;248m⡪/g;
s/17[78] /\\e[48;5;249;38;5;248m░/g;
s/17[56] /\\e[48;5;249;38;5;248m▒/g;
s/17[34] /\\e[48;5;249;38;5;248m▓/g;
s/17[12] /\\e[38;5;249;48;5;248m⡪/g;
s/170 /\\e[48;5;248m /g;
s/169 /\\e[48;5;248;38;5;247m⡪/g;
s/16[78] /\\e[48;5;248;38;5;247m░/g;
s/16[56] /\\e[48;5;248;38;5;247m▒/g;
s/16[34] /\\e[48;5;248;38;5;247m▓/g;
s/16[12] /\\e[38;5;248;48;5;247m⡪/g;
s/160 /\\e[48;5;247m /g;
s/159 /\\e[48;5;247;38;5;246m⡪/g;
s/15[78] /\\e[48;5;247;38;5;246m░/g;
s/15[56] /\\e[48;5;247;38;5;246m▒/g;
s/15[34] /\\e[48;5;247;38;5;246m▓/g;
s/15[12] /\\e[38;5;247;48;5;246m⡪/g;
s/150 /\\e[48;5;246m /g;
s/149 /\\e[48;5;246;38;5;245m⡪/g;
s/14[78] /\\e[48;5;246;38;5;245m░/g;
s/14[56] /\\e[48;5;246;38;5;245m▒/g;
s/14[34] /\\e[48;5;246;38;5;245m▓/g;
s/14[12] /\\e[38;5;246;48;5;245m⡪/g;
s/140 /\\e[48;5;245m /g;
s/139 /\\e[48;5;245;38;5;244m⡪/g;
s/13[78] /\\e[48;5;245;38;5;244m░/g;
s/13[56] /\\e[48;5;245;38;5;244m▒/g;
s/13[34] /\\e[48;5;245;38;5;244m▓/g;
s/13[12] /\\e[38;5;245;48;5;244m⡪/g;
s/130 /\\e[48;5;244m /g;
s/129 /\\e[48;5;244;38;5;243m⡪/g;
s/12[78] /\\e[48;5;244;38;5;243m░/g;
s/12[56] /\\e[48;5;244;38;5;243m▒/g;
s/12[34] /\\e[48;5;244;38;5;243m▓/g;
s/12[12] /\\e[38;5;244;48;5;243m⡪/g;
s/120 /\\e[48;5;243m /g;
s/119 /\\e[48;5;243;38;5;242m⡪/g;
s/11[78] /\\e[48;5;243;38;5;242m░/g;
s/11[56] /\\e[48;5;243;38;5;242m▒/g;
s/11[34] /\\e[48;5;243;38;5;242m▓/g;
s/11[12] /\\e[38;5;243;48;5;242m⡪/g;
s/110 /\\e[48;5;242m /g;
s/109 /\\e[48;5;242;38;5;241m⡪/g;
s/10[78] /\\e[48;5;242;38;5;241m░/g;
s/10[56] /\\e[48;5;242;38;5;241m▒/g;
s/10[34] /\\e[48;5;242;38;5;241m▓/g;
s/10[12] /\\e[38;5;242;48;5;241m⡪/g;
s/100 /\\e[48;5;241m /g;
s/99 /\\e[48;5;241;38;5;240m⡪/g;
s/9[78] /\\e[48;5;241;38;5;240m░/g;
s/9[56] /\\e[48;5;241;38;5;240m▒/g;
s/9[34] /\\e[48;5;241;38;5;240m▓/g;
s/9[12] /\\e[38;5;241;48;5;240m⡪/g;
s/90 /\\e[48;5;240m /g;
s/89 /\\e[48;5;240;38;5;239m⡪/g;
s/8[78] /\\e[48;5;240;38;5;239m░/g;
s/8[56] /\\e[48;5;240;38;5;239m▒/g;
s/8[34] /\\e[48;5;240;38;5;239m▓/g;
s/8[12] /\\e[38;5;240;48;5;239m⡪/g;
s/80 /\\e[48;5;239m /g;
s/79 /\\e[48;5;239;38;5;238m⡪/g;
s/7[78] /\\e[48;5;239;38;5;238m░/g;
s/7[56] /\\e[48;5;239;38;5;238m▒/g;
s/7[34] /\\e[48;5;239;38;5;238m▓/g;
s/7[12] /\\e[38;5;239;48;5;238m⡪/g;
s/70 /\\e[48;5;238m /g;
s/69 /\\e[48;5;238;38;5;237m⡪/g;
s/6[78] /\\e[48;5;238;38;5;237m░/g;
s/6[56] /\\e[48;5;238;38;5;237m▒/g;
s/6[34] /\\e[48;5;238;38;5;237m▓/g;
s/6[12] /\\e[38;5;238;48;5;237m⡪/g;
s/60 /\\e[48;5;237m /g;
s/59 /\\e[48;5;237;38;5;236m⡪/g;
s/5[78] /\\e[48;5;237;38;5;236m░/g;
s/5[56] /\\e[48;5;237;38;5;236m▒/g;
s/5[34] /\\e[48;5;237;38;5;236m▓/g;
s/5[12] /\\e[38;5;237;48;5;236m⡪/g;
s/50 /\\e[48;5;236m /g;
s/49 /\\e[48;5;236;38;5;235m⡪/g;
s/4[78] /\\e[48;5;236;38;5;235m░/g;
s/4[56] /\\e[48;5;236;38;5;235m▒/g;
s/4[34] /\\e[48;5;236;38;5;235m▓/g;
s/4[12] /\\e[38;5;236;48;5;235m⡪/g;
s/40 /\\e[48;5;235m /g;
s/39 /\\e[48;5;235;38;5;234m⡪/g;
s/3[78] /\\e[48;5;235;38;5;234m░/g;
s/3[56] /\\e[48;5;235;38;5;234m▒/g;
s/3[34] /\\e[48;5;235;38;5;234m▓/g;
s/3[12] /\\e[38;5;235;48;5;234m⡪/g;
s/30 /\\e[48;5;234m /g;
s/29 /\\e[48;5;234;38;5;233m⡪/g;
s/2[78] /\\e[48;5;234;38;5;233m░/g;
s/2[56] /\\e[48;5;234;38;5;233m▒/g;
s/2[34] /\\e[48;5;234;38;5;233m▓/g;
s/2[12] /\\e[38;5;234;48;5;233m⡪/g;
s/20 /\\e[48;5;233m /g;
s/19 /\\e[48;5;233;38;5;232m⡪/g;
s/1[78] /\\e[48;5;233;38;5;232m░/g;
s/1[56] /\\e[48;5;233;38;5;232m▒/g;
s/1[34] /\\e[48;5;233;38;5;232m▓/g;
s/1[12] /\\e[38;5;233;48;5;232m⡪/g;
s/10 /\\e[48;5;232m /g;
s/9 /\\e[48;5;232;38;5;0m⡪/g;
s/[78] /\\e[48;5;232;38;5;0m░/g;
s/[56] /\\e[48;5;232;38;5;0m▒/g;
s/[34] /\\e[48;5;232;38;5;0m▓/g;
s/2 /\\e[38;5;232;48;5;0m⡪/g;
s/1 /\\e[38;5;232;48;5;0m⡈/g;
s/0 /\\e[48;5;0m /g')\e[$poc_radku;0f\e[38;5;222;48;5;22m$info \e[00m\e[0;0f\e[?25h"

## Pokračování řádku 12: Ale pokud se nejedná o obrázek, nechť program zhyne
else exit 65
fi
Debian Sid/Experimental 64bit + Mate Desktop Environment
* CPU: Intel i5 3570
* GPU: NVIDIA GTX650 1GD5
* MB: Lenovo IH61M
* RAM: 16GiB Deutsche Demokratische Republik 3 @ 1600MHz

Roman Horník

#5
Trochu jsem tenhle prohlížeč obrázků po čase oprášil a podle mýho z něj vytáhnul co do kvality zobrazení maximum. Jo, aplikoval jsem tam to, čemu jsem se vyhejbal, takže umí barvy, ale je tam ještě něco navíc.
To navíc je skutečnost, že se nepracuje s fixní paletou terminálu, kde má bejt 256 barev, ale je jich kvůli duplicitám jen 249, z každýho obrázku si totiž vycucne optimální paletu až 256 barev z 16777216 možnejch. To trvá bohužel o něco dýl, protože se obrázek musí načíst dvakrát za sebou (možná ještě přijdu na to, jak tohle obejít), jednou kvůli paletě a jednou kvůli samotnýmu obrázku, kterej se na základě týhle palety musí přemapovat, k čemuž se navíc nepoužívaj decimální čísla, ale hexadecimální (vstup pro barvy č. 1 a 2 např.: 12 58 6 128 1 24 → \e]4;1;#0C3A06\a\e]4;1;#800118\a).
Bohužel, přemapování barev v terminálu se kvůli drastický úspoře času musí vykonat na černý "obrazovce", jinak totiž trvá neúnosně dlouho, přičemž předchozí obrázek, stále zobrazenej, přeblikává a postupně a relativně pomalu mění barvy (při každý změně se celej obsah překresluje).
Nicméně, protože tam už není znakovej dithering, mohl jsem si dovolit ještě jedno malý "kouzlo", který má za následek dvojnásobný horizontální rozlišení.
No a proč vlastně ta šaškárna s vlastní paletou barev, když terminál si ty hodnoty sám zaokrouhlí na barvy, který má ve vnitřní paletě? Protože by se jednak nezobrazily ani z daleka všechny barvy (tady se využije dostupný maximum), takže obraz může vypadat hrozně a jednak ta zabudovaná paleta neobsahuje barvy s nižší sytostí a jasem, takže zhruba do poloviny jasu by byly části obrázků černobílý. Přesto se ale terminálový zaokrouhlování používá, ale na barvy injektovaný palety.
Taky nepoužívám žádnej dithering - totiž často byl větším zlem, než současný "schody" jemnejch barevnejch přechodů - kolikrát se zbláznil a prskal příliš tmavý body vedle světlejch. U obrázků, kde má bod velikost jednoho pixelu to nevadí, ale u znaků je to vidět dost.

Jádro je zhruba stejný, akorát se nezpracovává vždycky jen jedna jasová hodnota (0-255) z obrázku typu PGM, ale rovnou 6 hodnot (taky každá 0-255), R, G, B popředí a R, G, B pozadí z obrázku typu PPM, kdy právě dvojnásobnýho vodorovnýho rozlišení dosahuju obarvováním znaku "▌" - levá půlka se obarví barvou popředí, pravá barvou pozadí. Dále se nepoužívá monstrózní míchátko pomocí sed, aby se z 24 odstínů šedi namíchalo asi 151 odstínů, pouze se šestice hodnot RGBRGB obalí do adekvátní ANSI sekvence (\e[38;2;R;G;B;m\e[48;2;R;G;B;m, který mimo jiný rozumí dokonce i šestnáctibarevná konzole (ale jen šestnáctibarevná, kde ty barvy jsou fixní). Takovej dvojznak, aby se vykreslil, ale potřebuje 26-32 bajtů (předtím to bylo jen 18-22 bajtů, ovšem, dlužno dodat, pro poloviční rozlišení).

Tady je kód. Nejsou tam žádný komentáře, ty lze víceméně odvodit z předchozí černobílý verze:

#!/bin/bash -e
sirka_zn=5
vyska_zn=8
presn_bc=8
interpol=1

if [ ! -f "$1" ]
  then exit 66
  elif grep -q image <<<`file "$1"`
then
poc_sloup=$((`tput cols`*12))
poc_radku=`tput lines`
sirka_okna=$((poc_sloup*sirka_zn))
vyska_okna=$((poc_radku*vyska_zn))
info_obr=`identify -format '%w %h' "$1"[0]`
sirka_obr=`awk '{print $1}' <<<$info_obr`
vyska_obr=`awk '{print $2}' <<<$info_obr`
pom_str_znaku="($sirka_zn/$vyska_zn)"

case "$2" in
  "") zoom=100;;
   *) zoom=`sed -e 's/,/./' <<<$2`;;
esac

if [ $((sirka_obr*vyska_okna)) -gt $((vyska_obr*sirka_okna/12)) ]
  then vyska_zobr=`bc -l <<<"scale=$presn_bc; $poc_sloup/$sirka_obr*$zoom*$pom_str_znaku/12"`
  else vyska_zobr=`bc -l <<<"scale=$presn_bc; $poc_radku/$vyska_obr*$zoom"`
fi

sirka_zobr=`bc -l <<<"scale=$presn_bc; $vyska_zobr/$pom_str_znaku*2"`

printf "\e[2J`convert -comment "" "$1"[0] \
-depth 8 -filter lanczos2 -resize $(bc -l <<< "$sirka_zobr*$interpol")%x$(bc -l <<< "$vyska_zobr*$interpol") \
-background black -gravity center -extent $(bc -l <<< "$poc_sloup*$interpol/6")x$(bc -l <<< "$poc_radku*$interpol")$3 -resize ${poc_sloup}x${poc_radku} \
-dither none -colors 256 -unique-colors -compress none ppm:- | tail -n+5 | xargs -n$((poc_sloup*poc_radku)) printf "%02x%02x%02x " | xargs -n1 | awk '{print "\033]4;" NR-1 ";#" $1 "\a"}' | tr -d '\n'`\e[?25l\e[0;0f$(convert -comment "" "$1"[0] \
-depth 8 -filter lanczos2 -resize $(bc -l <<< "$sirka_zobr*$interpol")%x$(bc -l <<< "$vyska_zobr*$interpol") \
-background black -gravity center -extent $(bc -l <<< "$poc_sloup*$interpol/6")x$(bc -l <<< "$poc_radku*$interpol")$3 -resize ${poc_sloup}x${poc_radku} \
-compress none ppm:- | tail -n+5 | xargs -n$(($poc_sloup/2)) | sed -e 's:$: :g;s:\([0-9]\+\) \([0-9]\+\) \([0-9]\+\) \([0-9]\+\) \([0-9]\+\) \([0-9]\+\) :\\e\[38;2;\1;\2;\3;48;2;\4;\5;\6m▌:g')\e[00m\e[0;0f\e[?25h"
else exit 65
fi


Vejšku a šířku znaku je potřeba nastavit podle jeho rozměrů v terminálu, 5×8 maj znaky v XTermu při velikosti "Tiny" (lze změnit pomocí [L-Ctrl] + [pravý myšítko]).
Jo a tady je menší galerie, jak to zobrazuje.
Debian Sid/Experimental 64bit + Mate Desktop Environment
* CPU: Intel i5 3570
* GPU: NVIDIA GTX650 1GD5
* MB: Lenovo IH61M
* RAM: 16GiB Deutsche Demokratische Republik 3 @ 1600MHz

Roman Horník

#6
Poslední verze, kterou jsem teď navíc pověsil na GitHub. Výrazně zjednodušená a zrychlená, protože minimálně XTerm a Mate/GNOME terminal uměj 24bitovou hloubku barev, takže odpadá pomalá procedura získání optimální palety barev obrázku a redefinice palety terminálu.

P. S.: Objevil jsem konkurenta, program catimg, kterej je v repu a kterej funguje snad jen náhodou na velmi podobným principu. Je sice o něco rychlejší, ale za cenu toho, že používá horší interpolaci a nevejde se zpravidla do okna terminálu. Samozřejmě neumí ani zoomovat.
Debian Sid/Experimental 64bit + Mate Desktop Environment
* CPU: Intel i5 3570
* GPU: NVIDIA GTX650 1GD5
* MB: Lenovo IH61M
* RAM: 16GiB Deutsche Demokratische Republik 3 @ 1600MHz