PhDr. Mgr. Jeroným Klimeš, Ph.D. 2026-04-24
Při přípravě knihy Křesťanství vztahy a sex do tisku jsem narazil na problém, že mám jen zdrojový graf v nevalné kvalitě a potřeboval bych ho předělat na nový, úhledný, ke kterému ovšem nemám zdrojová data. Samozřejmě šlo by to udělat ve GIMP nebo Photoshopu, ale řekl jsem si, že by bylo elegantnější řešení převést graf na data, digitalizovat ho a nový graf udělat z nich. Povedlo se, proto Vám přináším postup, který se může hodit kdekomu v nejrůznějších aplikacích, například vyčítání dat z historických papírových výstupů třeba teploty či seismografu.
Zdrojový graf popisuje, že náboženské společnosti mají asi o 30 % větší životaschopnost než sekulární (viz strana 116). Tento graf jsem potřeboval předělat.
Tento graf jsem v GIMPu očistil od os a legendy a rotoval o 90°.
Toto jsem dále rozdělil na dvě čáry a převedl na černobílý obraz, které jsem uložil do separátních souborů ve formátu PPM – ascii:
Černá čára PPM Červená čára PPM
Soubor PPM má přímočarou textovou strukturu
První tři řádky jsou hlavička, kde na třetí řádce jsou rozměry obrázku.
P3 # Created by GIMP version 3.0.4 PNM plug-in 280 255 # rozměry obrázku a konec hlavičky 255 # První bod – 3x255, tedy bílý 255 255 255 # Druhý bod – 3x255, tedy bílý 255 255 0 # Třetí bod – 3x0, tedy černý 0 0 255 # Čtvrtý bod – 3x255, tedy bílý 255 255
… atd. až do 280 × 255 × 3. řádky.
První řádka obrázku je tedy 280 × 3 = 840 řádek.
Skript v Bash
Teď stačilo napsat nedlouhý skript v Bash.
#/bin/bash
radka=280 # 280 znaku krat tri
celaradka=radka*3
hlavicka=3 # hlavicka ma 3-5 radek
i=0
counter=1
old=1000000
soubor_vstup="cerna_cara.ppm"
soubor_vystup=/dev/shm/picture_analyza_ppm_$(date +%Y-%m-%d_%H-%M-%S).txt
# shm je virtualni disk, takže neustále přepisování neničí SSD disk.
while read line
do
((i++))
if [ $i -le $hlavicka ]; then
continue; # preskoci hlavicku
else
if (( ( (i - hlavicka) % celaradka ) == 1 )); then
# testuje konec řádky obrázku.
# Konec řádky je posunut o hlavičku a zbytek, tedy modulus (%) po dělení délkou
# celé řádky je 1. Začátky nových řádek budou tedy (3+280×3×n+1), kde n je
# číslo řádky obrázku. Jsou to tedy čísla 844, 1684, 2524...
# Ale to nemusím řešit, mě zajímá jen ten zbytek.
((counter++))
if [ $old -lt 1000000 ]; then
echo -n "$old $counter " >> $soubor_vystup # vyexportuje
echo >> $soubor_vystup; # založí novou řádku obrázku
fi
echo -n $(( ((i-hlavicka) / celaradka ) + 1 ))" " >> $soubor_vystup;
# vyexportuje číslo obrazovkového řádku
counter=1
old=1000000 # začíná neznámou/nesmyslnou barvou
continue # načte další řádku ze souboru
fi
fi # konec přeskoku hlavičky.
if [ "$line" == "$old" ]; then
((counter++)) # pokud je tato řádka stejná jako předchozí, zvýší čítač.
else
if [ $old -lt 1000000 ]; then
# Smysluplné barvy (<256) vyexportuje bez konce řádky.
echo -n "$old $counter " >> $soubor_vystup
fi
counter=1 # založí nový čítač
old=$line
fi
done < $soubor_vstup # řádky načítá z tohoto souboru
Výstup ze skriptu
Přepočet černé čáry Přepočet červené čáry
S mírnou úpravou začátku a konce vypadá výstup takto:
1 255 795 0 45 255 0 2 255 753 0 87 255 0 3 255 678 0 138 255 24 4 255 600 0 192 255 48 5 255 555 0 201 255 84 6 255 528 0 153 255 159 7 255 498 0 105 255 237 8 255 468 0 90 255 282 9 255 438 0 90 255 312 10 255 411 0 90 255 339 11 255 381 0 90 255 369 12 255 351 0 90 255 399 13 255 321 0 90 255 429 14 255 297 0 87 255 456
Definice řádky:
Číslo_řádku(14) 1bílá_barva(255) #počet_1bílé(297) černá_barva(0) #počet_černé(87) 2bílá_barva(255) #počet_2bílé(456), kde 297+87+456=3*280=840
Tento skript načteme do Calcu (Excelu) a získaná čísla interpretujeme takto:
Hodnota čáry = #počet_1bílé + #počet_černé/2 = 297+87/2 = 340.5
Jinými slovy za vyčtenou hodnotu grafu považuji vzdálenost středu černé čáry od levého okraje grafu, proto jsem jej taky otočil.
Takto jsem načetl obě čáry grafu a přepočítal tak, aby byly v rozsahu y∈<0, 1> a x∈<0, 85>, popř. x∈<0, 115>, které jsem vyčetl z grafu. Jinými slovy, obrázek má rozměr třeba 280×340, tedy je musím z 280 udělat hodnoty 0 až 1 a z 340 udělat hodnoty 0 až 115. To je obyčejná trojčlenka:
stará_hodnota ku 340 se má jako nová_hodnota ku 115, tedy:
nová_hodnota=(stará_hodnota/340)*115.
Pak už je na vás, jaký program použijete na generování grafu. Já osobně jsem vcelku spokojený s Calcem, vychytávky dělám v R. Zde to byl graf typu X/Y.
Výsledný nový graf generovaný z vyextranovaných dat si stáhněte v Calc souboru i s grafem.
Pokud něco nechápete, zavolejte nebo napište email. Hlavně ale nezapomeňte poděkovat Hospodinovi za Linux a jeho tvůrce!