Rastrová grafika v PostScriptu

19. 7. 2007
Doba čtení: 13 minut

Sdílet

PostScript patří mezi takzvané grafické metaformáty, což znamená, že je v něm možné ukládat jak vektorovou, tak i rastrovou grafiku. V předchozích článcích jsme se zaměřili především na popis způsobů práce s vektorovou grafikou, dnes se podíváme na vkládaní bitmapových obrázků do PostScriptových dokumentů.

Obsah

1. Rastrová grafika v PostScriptu
2. Náhledové obrázky
3. Černobílé rastrové obrázky
4. Rastrové obrázky uložené ve stupních šedi
5. Plnobarevné rastrové obrázky
6. Literatura a odkazy na Internetu
7. Obsah dalšího pokračování tohoto seriálu

1. Rastrová grafika v PostScriptu

V perexu jsme si řekli, že PostScript patří mezi metaformáty, což v praxi znamená, že interpretery PostScriptu (značené také jako RIP – Raster Image Processors) dokáží zpracovat jak vektorové grafické informace, tak i informace rastrové, tj. bitmapy. Zařazením rastrových obrázků se sice poněkud snižuje přenositelnost dokumentů na různých tiskových zařízeních, protože každý RIP může rastrová data zpracovat odlišně, ale v současnosti je velmi mnoho grafických informací dostupných právě ve formě rastrových dat – typicky se jedná o fotografie a naskenované dokumenty; proto je nutné, aby i s těmito daty dokázal PostScript pracovat. PostScript nejenže dokáže rastrová data uložit přímo v těle dokumentu (není tedy zapotřebí používat externí soubory), ale při jejich ukládání je možné použít několik komprimačních metod, například LZW, CCITT nebo JPEG (založený na DCT).

V dnešní době může vypadat přinejmenším podivně, že se zdůrazňuje schopnost grafického formátu používat jak vektorová, tak i rastrová data, z minulosti však známe mnoho příkladů souborových formátů, které pracují pouze s jedním typem dat. Na jedné straně stojí čistě rastrové formáty, jakými jsou již v tomto seriálu popsané BMP, GIF, JPEG, PNG či TGA, na straně druhé zase formáty vektorové – PLT, DXF či SLD. Zlatou střední cestu představují metaformáty, mezi které patří PostScript, Portable Document Format (PDF), Scalable Vector Graphics (SVG) a v neposlední řadě také Windows Metafile (WMF) a Enhanced Windows Metafile (EMF), které sice zdaleka nejsou tak flexibilní jako PostScript, ale představují solidní základ pro přenos vektorových informací přes schránku (clipboard) v operačních systémech firmy Microsoft.

Ve druhé kapitole si ukážeme, jakým způsobem mohou být v PostScriptových souborech (většinou v EPS) uloženy náhledové bitmapové obrázky, které je možné použít například v dialozích pro otevření souboru nebo v textových procesorech či aplikacích typu DTP, které sice nemusí umět pracovat přímo s PostScriptem, ale mohou při tisku zkombinovat vložené PostScriptové soubory s vlastním zalomeným textem. Ve třetí kapitole bude ukázán postup při práci s černobílými obrázky (black and white), čtvrtá kapitola je věnována obrázkům uloženým ve stupněch šedi (grayscale) a kapitola pátá plnobarevným rastrovým obrázkům (truecolor).

2. Náhledové obrázky

Při práci s PostScriptovým formátem se často můžeme setkat s takzvanými náhledovými obrázky. Jedná se o jednoduché rastrové či (méně často) vektorové kresby, které by svým obsahem měly reprezentovat celý PostScriptový soubor. Náhledové obrázky je možné použít například v již zmiňovaných dialogových oknech pro vyhledávání a otevírání souborů nebo jako náhradní obrázek v textových procesorech, některých CAD systémech a DTP programech. Jedinou operaci, kterou tyto aplikace musí zvládat, je načtení a zobrazení náhledového obrázku a samozřejmě také začlenění celého PostScriptového souboru (který náhledový obrázek obsahuje) do svého výstupu. Vlastní zobrazení či tisk výsledného PostScriptu již musí zajistit programový nebo hardwarový RIP.

Mnoho novějších aplikací se sice pokouší o interpretaci PostScriptu vlastními silami (což mj. ukazuje na nekvalitní GUI nadstavbu OS, která by se o takové triviality měla postarat), ale když se podíváme například na renderovací schopnosti Microsoft Office, je jasné, že kvalitní hardwarový či programový RIP má v praxi stále své opodstatnění.

Náhledové obrázky mohou být vytvořeny několika způsoby. V některých případech se používají vložená rastrová data ve formátu TIFF nebo vektorová data uložená ve formátu WMF (Windows Metafile). Tato data jsou uložena ve formě binárních řetězců přímo v PostScriptovém souboru. Na počítačích Macintosh se místo rastrových dat ve formátu TIFF používá vložený náhledový obrázek uložený ve formátu PICT. Teoreticky je možné náhledové obrázky vkládat do úplných PostScriptových souborů (s příponou „.ps“, tyto soubory jsou již určeny pro tisk, tj. jde o finální výstup dokumentu), ale většinou se používají pro takzvaný Embedded PostScript (vkládaný PostScript), což jsou soubory s příponou „.eps“. Ve vkládaném PostScriptu je možné používat pouze omezený repertoár příkazů a na druhou stranu se musí v komentářích uvést základní informace o obrázku. Toto omezení je logické, protože aplikace pracující s těmito soubory musí mít alespoň ty nejdůležitější informace o geometrii obrázku.

Další možností vložení náhledového obrázku je použití formátovaných komentářů. S takto uloženými náhledovými obrázky se setkáme především u aplikací běžících pod Unixem a samozřejmě také pod Linuxem; programy určené pro Mac OS nebo Microsoft Windows používají převážně výše zmíněné formáty TIFF, WMF či PICT. Právě tutu možnost, která je ze všech nejjednodušší a také snadno pochopitelná, bude v této kapitole vysvětlena. Formátovaný komentář je ze syntaktického hlediska normální PostScriptový komentář (začíná znakem procenta), který však obsahuje dohodnutá klíčová slova a další číselné nebo textové informace. V tuto chvíli nás budou zajímat formátované komentáře, které se vztahují k náhledovým obrázkům. Samotný náhledový komentář začíná řádkem:

%%BeginPreview: šířka výška počet_bitů_na_pixel počet_řádků 

Za tímto komentářovým řádkem následují vlastní data obrázku, která jsou zakódována do dvouciferných hexadecimálních čísel. Podle nastaveného počtu bitů na pixel může každé číslo obsahovat informace o jednom pixelu (8 bitů na pixel), dvou pixelech (4 bity na pixel) nebo osmi pixelech (1 bit na pixel – velmi často používáno). Konec náhledového obrázku je indikován řádkem:

%%EndPreview 

Na následujícím ukázkovém příkladu je uvedena část PostScriptového kódu s náhledovým obrázkem, který má rozlišení 48×9 pixelů. Vzhledem k tomu, že je počet bitů na pixel nastaven na hodnotu 1 (černobílý obrázek), je pro každý obrazový řádek nutné zapsat celkem 48/8=6 dvouciferných hexadecimálních čísel, přičemž každý obrazový řádek náhledového obrázku je uložen v jednom textovém řádku PostScriptového souboru – to však není povinné, vztah mezi obrazovým řádkem a textovým řádkem je dosti volný. První a poslední komentářový řádek se nevztahuje pouze k náhledovému obrázku, ale k celému souboru, který samozřejmě může obsahovat i další vektorová a rastrová data. Všimněte si, že strukturované komentáře začínají buď znaky %! (hlavička souboru) nebo dvojicí znaků %%:

%!PS-Adobe-3.0 EPSF-2.0
%%BeginPreview: 48 9 1 9
% 0F FF FF FF FF F0
% FF 00 00 00 00 FF
% 0F F0 00 00 0F F0
% 00 FF 00 00 FF 00
% 00 0F F0 0F F0 00
% 00 00 FF FF 00 00
% 00 0F F0 0F F0 00
% FF 00 00 00 00 FF
% 0F FF FF FF FF F0
%%EndPreview

%%EOF 

3. Černobílé rastrové obrázky

Do PostScriptového souboru je možné vkládat rastrové obrázky prakticky libovolné velikosti, které mohou být uloženy v několika barvových prostorech (nejčastěji RGB a CMYK) a také mohou obsahovat variabilní počet bitů na pixel (bpp – bits per pixel). Nejjednodušší a nejsnáze přenositelné jsou černobílé rastrové obrázky (bitmapy), ve kterých je barva každého pixelu reprezentována pouze jedním bitem – v takové bitmapě je tedy možné rozlišit pouze dvě barvy, černou a bílou.

Černobílé bitmapy jsou podporovány již v PostScriptu Level 1, takže by s jejich zobrazením či tiskem neměl být problém ani na starších PostScriptových tiskárnách (problémy samozřejmě mohou nastat při přerastrování obrázku z jeho původního rozlišení do rozlišení dané tiskárny, to je však obecný problém všech bitmap). Černobílé rastrové obrázky se do PostScriptového souboru vkládají pomocí příkazu image, který vyžaduje celkem pět parametrů v následujícím pořadí:

šířka_bitmapy výška_bitmapy počet_bitů_na_pixel transformační_matice načítací_procedura image 

Význam jednotlivých parametrů je následující:

Parametr Význam parametru
šířka_bitmapy šířka bitmapy udávaná v pixelech (nikoli v délkových jednotkách)
výška_bitmapy výška bitmapy udávaná v pixelech
počet_bitů_na_pixel u černobílých bitmap má vždy hodnotu 1
transformační_ma­tice matice představující transformaci z uživatelského prostoru do souřadného systému obrázku
načítací_procedura zajišťuje data (bitový tok) reprezentující obrázek; může jít o obecnou proceduru, řetězec či soubor
image vlastní příkaz pro vykreslení bitmapy

Pomocí šířky a výšky je určen takzvaný souřadný systém obrázku (image space). Pokud má například obrázek rozlišení 320×240 pixelů, má souřadný systém obrázku rozměry 320×240 bezrozměrných jednotek, přičemž každý pixel obrázku je v tomto prostoru představován jednotkovým čtvercem (všimněte si, že v PostScriptu je pixel chápán jako plocha, nikoli bezrozměrný bod). Počátek souřadného systému obrázku, tj. bod o souřadnicích [0, 0], leží v levém dolním rohu, hranice tohoto systému, tj. souřadnice [šířka, výška] leží v pravém horním rohu. Při práci se souřadným systémem obrázku má smysl uvažovat pouze celočíselné koordináty, protože se adresují celé pixely a ne jejich části (subsampling se však interně provádí při vykreslování bitmapy). Na následujícím diagramu je ukázán souřadný systém obrázku spolu s pořadím jednotlivých pixelů tak, jak by je měla dodávat načítací procedura či v jakém pořadí by měly být uloženy v řetězci či externím souboru.

471
Souřadný systém obrázku

S využitím transformační matice předávané jako jeden z parametrů příkazu image je možné zapsat libovolnou lineární transformaci mezi uživatelským prostorem a souřadným systémem (prostorem) obrázku. Většinou se jedná pouze o zvětšení či zmenšení bitmapy spolu s jejím převrácením (zrcadlením) okolo horizontální či vertikální osy, je však možné zadat i jinou lineární transformaci včetně otáčení nebo zešikmení. Ve skutečnosti je nutné brát v úvahu i nastavení CTM, tedy aktuálně nastavené obecné transformační matice, takže obrázek (resp. jeho pixely) je transformován dvakrát. V příkladech uvedených v následujících dvou kapitolách bude ukázán pravděpodobně nejjednodušší způsob, jakým je možné obě transformační matice zkombinovat tak, aby byl výsledek předvídatelný.

Při požadavku na zobrazení černobílé bitmapy v měřítku 1:1 může mít příkaz image následující parametry:

šířka výška 1 [šířka 0 0 -výška 0 výška] data image 

Jak je z příkladu patrné, obsahuje transformační matice šestici hodnot. Čtyři hodnoty reprezentují změnu měřítka, natočení či zkosení, dvě hodnoty pak posun. Koeficienty transformační matice je možné zapsat ve tvaru [a11 a12 a21 a22 tx ty], kde je pomocí vektoru (tx, ty) specifikován posun. Předchozí zápis matice tedy znamená změnu měřítka v horizontálním směru o koeficient šířka, současně změnu měřítka ve vertikálním směru o koeficient -výška (jde tedy současně o zrcadlení okolo horizontální osy) a posun o vektor (0, výška), čímž je kompenzováno posunutí obrázku ve vertikálním směru vlivem zrcadlení. S takto zapsanou transformační maticí se můžeme setkat nejčastěji.

4. Rastrové obrázky uložené ve stupních šedi

Druhou skupinou obrázků jsou rastrové obrázky uložené ve stupních šedi (grayscale). I tento typ obrázků je podporován ve většině PostScriptových zařízení, ale při jejich zpracování je nutné mít na mysli, že u některých typů tiskáren (laserové tiskárny, osvitové jednotky apod.) dochází při vykreslování obrázků k ditheringu, při kterém jsou odstíny šedi nahrazovány rastrem složeným pouze z černých a bílých bodů. Extrémní případ ditheringu je možné vidět v nekvalitně tištěných novinách s malým rozlišením fotek. Obrázky ve stupních šedi (grayscale) se od černobílých obrázků odlišují především větší bitovou hloubkou. Zatímco se u černobílých obrázků používal pro popis pixelu pouze jeden bit, může se u obrázků ve stupních šedi pro popis pixelu použít 2 bity (čtyři odstíny), 4 bity (šestnáct odstínů), 8 bitů (256 odstínů) či dokonce 12 bitů (4096 odstínů). O obrázků se dvěma, čtyřmi či dvanácti bity na pixel je zapotřebí zajistit, aby začátek každého obrazového řádku začínal na celém bytu.

Příklad obrázku ve stupních šedi, ve kterém jsou jednotlivé pixely uloženy v hexadecimálním řetězci, je patrný z následujícího výpisu. Použití hexadecimálního řetězce je celkem časté, i když se nejedná o nejvíce úsporný způsob zápisu. Je to však jednoduchý a přímočarý způsob, jak do PostScriptových souborů vkládat rastrová data:

100 100 translate       % transformace posunu uložená do CTM
40 30   scale           % transformace změny měřítka přidaná do CTM
40 30                   % šířka a výška bitmapy
8                       % 8 bitů na pixel
[40 0 0 -30 0 30]       % transformační matice – vertikální přeprácení
{<                      % začátek řetězce kódovaného hexadecimálně
ff00ff1020304050
... % další data
80a0ff1020304050
>}                      % konec hexadecimálně zakódovaného řetězce 

V praxi bývají obrazová data i procedura pro jejich načtení vytvářena různým způsobem. Níže je uvedena část PostScriptového souboru obsahujícího nám už známý obrázek Leny převedený do odstínů šedi (celý soubor je možné získat zde). Místo přímého zápisu hexadecimálního řetězce jako parametru příkazu image je zde použit jiný způsob – zápis těla procedury, tj. { picstr readstring }, přičemž samotný hexadecimální řetězec s obrazovými daty je v tomto případě uložen až za příkazem image.

Všimněte si také strukturovaných komentářů s definicí takzvaného bounding boxu, tj. oblasti, ve které se celý obrázek nachází. Bounding box je používán například při vkládaní Embeded PostScriptového souboru do jiného PostScriptového souboru. Níže uvedený příklad je na takovou operaci připraven – pomocí příkazu grestore obnovuje grafický stav, neobsahuje příkaz pro vykreslení stránky (ten je zakomentován) a obsahuje korektně zapsaný bounding box.

472
Obrázek Leny převedený do odstínů šedi
%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
%%Title: lena2.ps
%%Pages: 1
%%BoundingBox: 267 357 344 434
%%EndComments
/readstring {
  currentfile exch readhexstring pop
} bind def
/picstr 80 string def
%%EndProlog
%%Page: 1 1
gsave
267.6 357.6 translate
76.8 76.8 scale
80 80 8
[ 80 0 0 -80 0 80 ]
{ picstr readstring }
image
9f9e9b9a9a9da7aca17f5d626968696a6d757b7d81838181838585858484
858585838183838384838581818080807d7d766e6e89999d97989a999999
9a9b9ab6d6d48a6b75767a787a7c7b7b7d7b79849b9c9c9b999fa8a89c7c
5a5f676966676d747b7d7f81828282838484848483828282818281828481

% zde je uloženo dalších cca 11kB dat

2720242b2f2a402c352f43382a2b29313e2e3a444d52545757595a5a5d5c
5d6061636364666566676a6c70747981868b8f8a453e444f5854585a473a
353c384757482b202a3e
grestore
%showpage - odkomentovat pro zobrazení v softwarovém RIPu
%%Trailer 

5. Plnobarevné rastrové obrázky

Plnobarevné obrázky (truecolor), které jsou plně podporovány až v PostScriptu Level 2, se zapisují poněkud složitějším způsobem, než obrázky černobílé či obrázky ve stupních šedi. Důvod je jednoduchý – zatímco u černobílých obrázků se z každé hodnoty uložené v bitmapě přímo počítala světlost pixelu, je u obrázků barevných nutné specifikovat nějaký barvový prostor. Vzhledem k tomu, že dva nejpoužívanější barvové prostory, tj. RGB a CMYK, obsahují jiný počet barvonosných kanálů, je v PostScriptu dostupný příkaz colorimage, který dokáže pracovat s libovolným množstvím těchto kanálů. Způsob předávání parametrů do příkazu colorimage je následující:

šířka_bitmapy výška_bitmapy počet_bitů_na_barvovou_složku transformační_matice načítací_procedura_1 načítací_procedura_n multi počet_kanálů colorimage 

Některé parametry, jakými jsou šířka a výška bitmapy, už známe. Mění se parametr s počtem bitů, který nyní neudává počet bitů na pixel, ale počet bitů na jednotlivé barvové složky. Dále se místo jedné načítací procedury může specifikovat procedur několik. U barvového prostoru RGB jsou to většinou tři procedury, u prostoru CMYK pak procedury čtyři. Následuje parametr multi, což je logická hodnota true/false, pomocí které se specifikuje, zda jsou jednotlivé barvové složky uložené za sebou nebo se jedná o separátní bitmapy. Posledním parametrem je číslo udávající počet kanálů. Většinou se jedná o tři či čtyři kanály.

Následuje část demonstračního příkladu (plná verze je dostupná zde) s plnobarevným obrázkem Leny. Obrazová data jsou uložena v jednou řetězci, proto je parametr multi nastaven na pravdivostní hodnotu true. Počet kanálů je nastaven na tři (RGB) a počet bitů na jednotlivou barvovou komponentu v kanálu má hodnotu 8. To znamená, že jeden pixel je reprezentován 3×8=24 bity:

%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
%%Title: logo.ps
%%Pages: 1
%%BoundingBox: 267 357 344 434
%%EndComments
/readstring {
  currentfile exch readhexstring pop
} bind def
/rpicstr 80 string def
/gpicstr 80 string def
/bpicstr 80 string def
%%EndProlog
%%Page: 1 1
gsave
267.6 357.6 translate
76.8 76.8 scale
80 80 8
[ 80 0 0 -80 0 80 ]
{ rpicstr readstring }
{ gpicstr readstring }
{ bpicstr readstring }
true 3
colorimage
e1e1dededddfe7eae6c99fa7afb2b2b0b4bec5c9cbcdcacacdd1d2d1cecf
cfcfcdcbcccccdcfd1cecfcbcacbc8c9c8c2baafbed2dbdbdadbdedddddf
dedbdcf0faefaab2b9bbbbbec3c2c0c1c4bfc2d688878483818690968760

% zde je uloženo dalších cca 11kB dat

373d39556848231829413b4183ab955b727a7f694541465154536e576a5c
796b4d5551696a3f404550504e59535758595d5a6063656767696a696a6e
7278808891a1aeb7b69f5453595d575359584c4f54554d66735b423a4150
grestore
%showpage - odkomentovat pro zobrazení v softwarovém RIPu
%%Trailer 

473
Plnobarevný obrázek Leny

bitcoin_skoleni

6. Literatura a odkazy na Internetu

  1. Wikipedia: PostScript,
    http://en.wiki­pedia.org/wiki/Pos­tScript
  2. Paul Bourke: PostScript Tutorial,
    http://local.was­p.uwa.edu.au/~pbou­rke/dataformat­s/postscript/
  3. A First Guide to PostScript,
    http://www.ta­ilrecursive.or­g/postscript/pos­tscript.html
  4. Thomas Merz:
    PostScript & Acrobat/PDF : Applications, Troubleshooting, and Cross-Platform Publishing,
     1996
  5. Ross Smith:
    Learning PostScript : A Visual Approach
    Published 1990
  6. Henry McGilton, Mary Campione:
    PostScript by Example
     1992
  7. Adobe Systems Incorporated, Glenn C. Reid:
    PostScript Language Program Design
     1988
  8. Adobe Systems Incorporated:
    PostScript Language Reference Manual
     1990
  9. Adobe Systems Incorporated:
    PostScript Language Tutorial and Cookbook
     1985
  10. Adobe Systems Incorporated:
    Programming the Display PostScript System With X
     1993

7. Obsah dalšího pokračování tohoto seriálu

V následujících pokračováních seriálu o grafických formátech dokončíme popis vkládání rastrových obrázků do PostScriptových souborů (ještě jsme si neřekli, jak se tvoří bitové masky a ořezové cesty) a také se začneme zabývat dalším známým a velmi dobře navrženým vektorovým formátem. Jedná se o souborový formát nazvaný Scalable Vector Graphics, neboli SVG, který je založený na značkovacím jazyku Extensible Markup Language – XML.

Autor článku

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