Hlavní navigace

Finišujeme s PNG - Textové metainformace a kalibrační data

12. 10. 2006
Doba čtení: 13 minut

Sdílet

V závěrečné části našeho krátkého seriálu, ve kterém se zabýváme populárním grafickým formátem PNG, si popíšeme zbývající důležité chunky. Probereme si zejména ty, které se týkají barvových profilů a ukládání textových metainformací o obrázku.

Obsah

1. Zápis metainformací pomocí textových chunků
2. Chunky tEXt a zTXt – textové informace o obrázku
3. Chunk iTXt – pište poznámky v klingonském jazyce
4. Chunk gIFt – žádný dárek
5. Chunk gIFg – informace o konverzi z grafického formátu GIF
6. Chunk gIFx – rozšiřující aplikační bloky grafického formátu GIF 89a
7. Chunk gAMA – změna γ faktoru
8. Chunk iCCP – ICC profil
9. Obsah dalších článků na téma grafických formátů

1. Zápis metainformací pomocí textových chunků

Už při popisu grafického formátu GIF (viz /serialy/graficky-format-gif/) jsme si ukázali, že kromě vlastního obrázku, tj. barvové palety a rastrových dat, je možné do souboru typu GIF ukládat i textové a binární metainformace popisující buď vlastní obrázek (datum vytvoření, zdroj obrazových dat aj.) nebo informace dodávané programem, který obrázek vytvořil či modifikoval. Textové informace jsou uloženy ve speciálním bloku a binární informace v rozšiřujících blocích, které si může vytvořit každá aplikace pro své účely.

Tento způsob práce s přídavnými informacemi o obrázku používá například známý program FractInt a jeho následovníci (XFractInt, FractInt for Windows) pro uložení informací o fraktálu, který je obrázkem reprezentován. V praxi to znamená, že při přenosu obrázku s fraktálem na jiný počítač je možné parametry fraktálu zpětně načíst a například vygenerovat obrázek s vyšším rozlišením, změnit barvovou paletu, pohled na fraktál (zoom) apod.

Textové komentáře uložené v grafickém formátu GIF však zdaleka nejsou dokonalé, a to zejména ze tří důvodů:

  1. Specifikace grafického formátu GIF přesně neříká, jak mají textové komentáře vypadat a jaké údaje mají obsahovat. To působí problémy zejména při dalším zpracovávání obrázků, například vyhledání všech obrázků vytvořených v nějakém časovém období nebo určitým programem či zařízením. Některé aplikace do obrázku vkládají množství důležitých informací, jiné pouze údaj o copyrightu nebo zprávu, že se jedná o neregistrovaný shareware.
  2. Ve specifikaci také není řečeno (a především v praxi dodržováno) zachování komentářů při modifikaci obrázku nějakým konverzním programem nebo grafickým editorem. To znamená, že se i při (na první pohled neškodné) manipulaci s obrázkem mohou důležité informace ztratit, nebo je může konverzní program přepsat jinými informacemi.
  3. V době vzniku GIFu byla počítačová síť CompuServe zaměřena především na anglicky mluvící uživatele, takže textový formát je založen na sedmibitovém ASCII. Rozšíření na osm bitů je sice proveditelné, ale není zaručeno korektní zpracování a zobrazení takových informací na různých operačních systémem nebo v různých jazykových mutacích. O vymoženostech typu UTF-8 se samozřejmě v době vzniku GIFu neuvažovalo.

Grafický formát PNG se snaží všechny tři výše zmíněné nevýhody textových komentářů odstranit a dokonce jde ještě dále, protože i textové informace je možné (podobně jako informace grafické) komprimovat a tak dále ušetřit drahou paměťovou kapacitu a snížit přenosové časy. V dalších čtyřech kapitolách budou popsány chunky určené pro zápis textových metainformací o obrázku. Jedná se o chunky tEXt, zTXt, iTXt, gIFt, gIFg a gIFx.

2. Chunky tEXt a zTXt – textové informace o obrázku

Základním chunkem určeným pro uložení textových informací je chunk nazvaný tEXt. Tento chunk se může v grafickém souboru vyskytovat na libovolném místě, tj. jak před, tak i za obrazovými daty, a dokonce může být těchto chunků uložen větší počet, což se také velmi často používá. Ihned za délkou a jménem chunku se nachází textová oblast obsahující znaky ze znakové sady Latin-1. Ta obsahuje dva řetězce oddělené bytem s nulovou hodnotou. První řetězec obsahuje klíčové slovo (viz další tabulku) a druhý řetězec, který může být i dosti dlouhý, reprezentuje vlastní informační obsah. Mezi definovaná klíčová slova patří:

Klíčové slovo Význam
Title jednořádkový titulek obrázku (může být zobrazeno prohlížečem v titulkovém pruhu)
Author jméno autora obrázku (člověka, ne aplikace)
Description popis obrázku, může být delší než Title
Copyright informace o ©, například, zda je možné obrázek dále šířit či tisknout
Creation Time čas vytvoření obrázku formátovaný podle RFC 822
Software jméno a verze aplikace, která byla použita pro vytvoření obrázku, může zde být specifikováno (podepsáno) i více aplikací
Disclaimer textová informace o možném použití obrázku
Warning informace s varováním o „závadném“ obsahu obrázku
Source zařízení, pomocí kterého byl obrázek vytvořen
Comment libovolný komentář, typicky získaný z komentářů GIFu při konverzích

Kromě toho se často používá i neoficiální klíčové slovo Caption, které má podobný význam jako Title, ovšem může obsahovat delší text (není požadováno zkrácení z důvodu zobrazení v titulkovém pruhu).

Chunk nazvaný zTXt má stejný význam jako chunk tEXt, ovšem s tím rozdílem, že textová data jsou zkomprimována stejným algoritmem jako data obrazová. To má své přednosti i zápory. Předností je samozřejmě menší objem dat, což je výhodné zejména u rozsáhlého obsahu klíčových slov Description a Disclaimer (prostě právníci…), záporem však je fakt, že se textová informace nedá přečíst například při prohlížení obrázku textovým nebo hexadecimálním editorem. Z tohoto důvodu je vhodné chunk zTXt použít pro dlouhé textové chunky a krátké texty (Title, Author, Creation Time) ponechat ve své ASCII (resp. Latin-1) podobě.

Příklad použití textového chunku tEXt je ukázán na prvním demonstračním obrázku, do kterého jsem pomocí aplikace pngcrush přidal klíčové slovo Title s obsahem Lena. Obsah souboru je následující:

offset: 00000008  jméno chunku: IHDR   délka chunku: 13
offset: 00000021  jméno chunku: tEXt   délka chunku: 10
offset: 00000037  jméno chunku: IDAT   délka chunku: 108684
offset: 0001a8cf  jméno chunku: IEND   délka chunku: 0 

Chunk tEXt má v tomto obrázku strukturu:

00 00 00 0a
74 45 58 74
54 69 74 6c
65 00 4c 65
6e 61 d4 49
a5 d4 

kde jednotlivé byty mají význam:

Skupina bytů Význam
00 00 00 0a délka datové části chunku je 10 bytů
74 45 58 74 text ‚tEXt‘ – název chunku
54 69 74 6c 65 text ‚Title‘ – klíčové slovo
00 oddělovač (znak s kódem 0)
4c 65 6e 61 text ‚Lena‘
d4 49 a5 d4 kontrolní součet (CRC)

png6_1

Obrázek 1: PNG s povinnými chunky IHDR, IDAT a IEND a nepovinným chunkem tEXt

3. Chunk iTXt – pište poznámky v klingonském jazyce

Chunk nazvaný iTXt vznikl rozšířením výše popsaných chunků tEXt a zTXt. Jedná se o chunk určený pro zápis informací v libovolném (lidském) jazyce, přičemž je text možné ponechat v nezměněné podobě či ho zkomprimovat metodou deflate. Chunk má již poněkud složitější strukturu, protože obsahuje klíčové slovo pojmenované v angličtině (uložené v kódování Latin-1), příznak komprimace, označení jazyka, přeložené klíčové slovo a vlastní text (oboje v kódování UTF-8). Všechny řetězcové položky chunku jsou od sebe odděleny bytem s kódem 0. Některé položky mohou mít nulovou délku (pozor při programování!), oddělovače je však i v tomto případě nutné použít. Struktura chunku iTXt je následující:

Délka Význam
1–79 klíčové slovo (jméno) v kódování Latin-1
1 oddělovač, znak s kódem 0
1 příznak (0,1), zda je text komprimován
1 komprimační metoda (prozatím vždy 0 – deflate)
>=0 označení jazyka podle RFC 1766
1 oddělovač, znak s kódem 0
>=0 přeložené klíčové slovo v kódování UTF-8
1 oddělovač, znak s kódem 0
>=0 vlastní text uložený v kódování UTF-8

Nejzajímavější položka v tomto chunku je označení jazyka, které musí odpovídat RFC 1766 (http://www.i­etf.org/rfc/rfc176­6.txt). Jedná se o ASCII řetězec, ve kterém jsou skupiny znaků od sebe odděleny pomlčkou (řetězec může obsahovat pouze znaky pomlčky a písmena velké i malé abecedy). První dva znaky před pomlčkou většinou určují jazyk podle kódu ISO 639 (http://www.ic­s.uci.edu/pub/i­etf/http/rela­ted/iso639.txt), ale je možné použít i jednoznakový či naopak víceznakový prefix, například x-klingon.

Také je zajímavé, že klíčové slovo, tj. označení vlastního obsahu chunku, je uvedeno jak v angličtině v kódování Latin-1 (de facto však pouze v ASCII), tak i ve vybraném jazyce, tentokrát již v „mezinárodním“ kódování UTF-8. To může do značné míry pomoci aplikacím, které mohou hledat klíčová slova pouze anglicky (je to mnohem jednodušší), ale uživateli se vypíše slovo přeložené (např. čínsky nebo hebrejsky) bez toho, aby aplikace musela daný jazyk nějak složitě podporovat.

4. Chunk gIFt – žádný dárek

Chunk nazvaný gIFt slouží pro uložení informací získaných při převodu obrázku z grafického formátu GIF 89a, který podporuje plain-textové rozšíření. Kromě textových informací jsou v tomto chunku uložena i další data získaná z GIFu, například pozice textu v rámci obrázku nebo barva textu a jeho pozadí. Jedná se o nedoporučovaný chunk, avšak některé konverzní aplikace s ním stále pracují (ovšem nevím o žádné aplikaci, která by text zobrazovala takovým způsobem jako u GIFu). Formát tohoto chunku je následující:

Délka bloku Význam
4 byte levá souřadnice textového rámce
4 byte horní souřadnice textového rámce
4 byte šířka textového rámce v pixelech
4 byte výška textového rámce v pixelech
1 byte šířka znaků v pixelech (neproporcionální font)
1 byte výška znaků v pixelech
3 byte barva textu (formát RGB)
3 byte barva pozadí textu (formát RGB)
n bytů vlastní text, který může být automaticky přeformátován do specifikované­ho rámce

Prohlížecí program by měl nejprve zjistit pozici a rozměry textového rámce a posléze rámec vyplnit barvou pozadí textu. Do rámce by se zadaný text měl naformátovat a zobrazit specifikovanou barvou, přičemž použitý font při vykreslování by měl odpovídat zadané šířce a výšce znaků, nebo se těmto rozměrům alespoň blížit – v podstatě se jedná o pozůstatek DOSu. Vlastní formátování (rozdělení textu do řádků) je ponecháno na prohlížecím programu, stejně jako výběr konkrétního fontu.

5. Chunk gIFx – rozšiřující aplikační bloky z grafického formátu GIF

Chunky gIFg a gIFx slouží pro uložení dalších informací získaných při konverzi obrázku z grafického formátu GIF. Na první pohled se může zdát, že se PNG na GIF příliš váže, musíme si však uvědomit, že se jedná (či by se ve většině případů mělo jednat) o přímého nástupce GIFu a tvůrci PNG díky těmto chunkům zajistili zachování prakticky všech informací, které je možné v GIFu ukládat.

Chunk nazvaný gIFg ve svém těle nese informaci ukládanou v grafickém řídicím bloku GIFu 89a. Tento blok je v GIFu použit zejména při tvorbě animací. Ty sice PNG přímo nepodporuje (zajišťuje je jeho bratříček MGN – Multi-image Network Graphics), ale přesto je možné informaci z grafického řídicího bloku pro daný snímek zachovat, například pro pozdější konverzi do některého z formátů podporujících animaci. Tento chunk má následující strukturu:

Délka bloku Význam
1 byte způsob překreslení snímku (disposal method)
1 byte příznak, zda je vyžadován vstup od uživatele před zobrazením snímku
2 byty zpoždění zobrazení snímku zadané v setinách sekundy (jako v GIFu)

6. Chunk gIFx – rozšiřující aplikační bloky grafického formátu GIF 89a

Chunk nazvaný gIFx slouží pro uložení rozšířených informací jednotlivých aplikací (viz například výše zmíněný program FractInt). Chunk obsahuje stejný identifikátor aplikace i její kód, jaký je uložený v GIFu, takže se žádné důležité informace při konverzi neztrácí (informace o průhlednosti nahrazuje plný alfa kanál). Formát tohoto chunku je zobrazený v následující tabulce:

Délka bloku Význam
8 bytů jednoznačný identifikátor aplikace v kódování ASCII
3 byty kód aplikace (například její verze)
n bytů data uložená danou aplikací, formát je libovolný (proud bytů)

7. Chunk gAMA – změna γ faktoru

V první části tohoto seriálu jsme si řekli, že si při zobrazování rastrových obrázků na různých počítačových platformách (PC, SGI, Sun, Macintosh) či na televizní obrazovce můžeme všimnout, že zatímco je obrázek na jedné platformě příliš tmavý, na jiné platformě je zase moc světlý, přičemž dochází ke splývání nejsvětlejších nebo nejtmavších barevných odstínů. Pokud se například obrázek vytvořený na Macintoshi přenese na PC, je při zobrazení většinou velmi tmavý a naopak. Je to způsobeno rozdílným nastavením takzvaného koeficientu gama (γ). Většina zobrazovacích zařízení (CRT, LCD) je totiž nelineární v tom smyslu, že na lineární změnu signálu na svém vstupu reagují nelineární změnou světlosti zobrazovaných pixelů. Také lidské oči (ale i uši) reagují na své „vstupy“ nelineárně, takže je mnohdy složité korektně přenést a zobrazit obrázky v celé své barevné škále.

Právě zde přichází ke slovu takzvaná „gama korekce“, jejímž účelem je obrázek před jeho zobrazením předpřipravit tak, aby po průchodu celým zobrazovacím řetězcem zůstala v co největší míře zachována linearita. V grafickém formátu PNG je možné uchovat gama faktor zařízení, které obrázek vytvořilo (skener, fotoaparát, počítačový program). Při zobrazování se na základě tohoto gama faktoru mohou intenzity pixelů přepočítat a dosáhnout tak kýžené linearity. Důležité je, že gama korekci je možné provádět beze změny hodnot pixelů původního obrázku, takže při úpravách a přenosu na další platformu nedochází ke ztrátě dynamiky barev.

Vzorec pro gama korekci je poměrně jednoduchý:

barvová_složka=po­žadovaná_inten­zitagama

Ve formátu PNG je hodnota gama faktoru uložena v chunku nazvaném gAMA. Tento chunk obsahuje pouze jednu celočíselnou hodnotu (4 byty), která reprezentuje gama faktor vynásobený hodnotou 10 000 a zaokrouhlený na nejbližší celé číslo. Typické hodnoty uložené v chunku gAMA jsou shrnuty v další tabulce:

Platforma gAMA
PC 45 455
Macintosh 65 909
SGI 77 273
NeXT 100 000

Gama korekce nemusí být složitě a zdlouhavě prováděna pro každý pixel zvlášť, postačí použít vyhledávací tabulku. V případě obrázků typu grayscale nebo truecolor s osmibitovými barvovými složkami obsahuje vyhledávácí tabulka pouze 256 položek typu byte a její výpočet je velmi jednoduchý:

// tato funkce vytvoří vyhledávací tabulku
// o délce 256 položek s vypočtenou
// korekcí zadanou exponentem "g"
void gamma_fp(uint8 G[256], double g)
{
    int i;
    G[0]=0;
    for (i=1; i<=255; i++)
        G[i]=pow(i/255.0, g)*255+0.5;
} 

Každý pixel je před svým zobrazením převeden pomocí této vyhledávací tabulky, přičemž pro plnobarevné obrázky je zapotřebí konverzi provést pro každou barvovou složku zvlášť (tj. třikrát pro jeden pixel, α-kanál není gama korekcí upravován). Následuje ukázka obrázku, který obsahuje chunk gAMA:

offset: 00000008  jméno chunku: IHDR   délka chunku: 13
offset: 00000021  jméno chunku: gAMA   délka chunku: 4
offset: 00000031  jméno chunku: IDAT   délka chunku: 8192
offset: 0000203d  jméno chunku: IDAT   délka chunku: 8192
offset: 00004049  jméno chunku: IDAT   délka chunku: 8192
offset: 00006055  jméno chunku: IDAT   délka chunku: 8192
offset: 00008061  jméno chunku: IDAT   délka chunku: 8192
offset: 0000a06d  jméno chunku: IDAT   délka chunku: 8192
offset: 0000c079  jméno chunku: IDAT   délka chunku: 8192
offset: 0000e085  jméno chunku: IDAT   délka chunku: 8192
offset: 00010091  jméno chunku: IDAT   délka chunku: 8192
offset: 0001209d  jméno chunku: IDAT   délka chunku: 8192
offset: 000140a9  jméno chunku: IDAT   délka chunku: 8192
offset: 000160b5  jméno chunku: IDAT   délka chunku: 8192
offset: 000180c1  jméno chunku: IDAT   délka chunku: 8192
offset: 0001a0cd  jméno chunku: IDAT   délka chunku: 2168
offset: 0001a951  jméno chunku: IEND   délka chunku: 0 

png6_2

Obrázek 2: PNG s povinnými chunky IHDR, IDAT a IEND a nepovinným chunkem gAMA

8. Chunk iCCP – ICC profil

Pro profesionální barevný tisk samotná informace o gama korekci nemusí být dostačující, protože každý barvový kanál (RGB) může vykazovat jinou nelinearitu, která může vést buď ke ztrátě dynamiky barev nebo dokonce k celkovému rozpadu spektra. Zde přichází ke slovu změna barevnosti (chromacity) prováděná v barvovém prostoru x-y definovaném konsorciem CIE (Commission Internationale de L'Eclairage resp. Interna­tional Commission on Illumination) a kompletní barevné profily ICC. Při prohlížení obrázků umístěných na webu se většinou setkáme pouze s ukládanou informací o gama korekci, plný barevný profil ICC je spíše výjimkou a mnohdy i zbytečným luxusem, který zvětšuje celkovou velikost souboru i o stovky bytů (typicky se jedná o hodnoty 200–300 bytů v závislosti na množství informací uložených v ICC profilu, není však problém narazit i na profily o délce několika desítek kilobytů).

O uložení ICC profilů se stará chunk se jménem iCCP, který má poměrně komplikovanou strukturu; veškerá komplikovanost je skryta ve čtvrtém datovém bloku chunku:

Délka sekvence Význam
1–79 bytů jméno profilu v kódování Latin-1
1 byte oddělovač jména profilu (jeho délka se mění)
1 byte komprimační metoda (0-deflate)
n bytů vlastní ICC profil

Ve skutečnosti není požadováno, aby prohlížecí či editační program ICC profilu plně porozuměl. Jediné, co musí – alespoň teoreticky – provést, je dekomprimace údajů o ICC profilu a předání těchto údajů grafickému subsystému, který dodané informace zpracuje a obrázek korektně zobrazí či vytiskne. Podle dostupných informací se tímto způsobem řídí pouze některé prohlížecí a editační programy běžící většinou na platformě Macintosh.

V souvislosti s použitím grafického formátu PNG v pre-presu a profesionálním barevném tisku je nutné říci, že PNG je takřka výhradně postaveno na barvovém modelu RGB, takže není možné pracovat (tj. ukládat barvy pixelů) přímo v jiném barvovém modelu, a to ani s CIE XYZ či CMYKem. V případě, že je CMYK nutné z nějakého důvodu použít, je vhodné uvažovat o jiném grafickém formátu, například o TIFFu, který CMYK v některých svých režimech přímo podporuje. Díky existenci barevných profilů však potřeba přímého použití CMYKu v souborových formátech není tak velká, takže spíše záleží na vlastnostech použitých aplikací i tiskových zařízení a ne přímo na použitém barvovém režimu.

root_podpora

9. Obsah dalších článků na téma grafických formátů

V následujícím pokračování tohoto seriálu si popíšeme grafický formát, který je sice často používaný, ale mezi programátory i uživateli z několika důvodů poměrně neoblíbený. Jedná se o formát BMP ve verzi pro Microsoft Windows (formát se stejným jménem i koncovkou existuje ve variantě pro OS/2). Popíšeme si i některé málo známé informace o tomto grafickém formátu.

Byl pro vás článek přínosný?

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.