Technický článek

Měkké masky a zploštění průhlednosti v Delphi

PDF Library for Delphi vytváří z Delphi oba druhy měkkých masek PDF. SetImageSoftMaskEx připojí maskovací obrázek k cílovému obrázku a umí zapsat položku /Matte, kterou potřebuje grafika s předvynásobenou alfou. NewSoftMaskGraphicsState sestaví alfa nebo luminanční masku ze zachyceného obsahu a vrátí stav grafiky, který aplikujete na následující kreslení. A když spotřebitel neumí zpracovat průhlednost vůbec, FlattenTransparency vykreslí vizuální výsledek a nahradí jím každou stránku

Měkké masky jsou to, jak PDF vyjadřuje přechodové vytrácení, vinětaci, fotografii prolnutou s pozadím a každý další efekt, kde se krytí mění napříč oblastí. Konstantní průhlednost je jedno číslo ve stavu grafiky; měkká maska je celá funkce polohy, a dokud ji neumíte vytvořit, celá kategorie designu se nedá reprodukovat

Dva typy masky a co každý z nich čte

Alfa maska bere své hodnoty z alfa kanálu maskovacího obsahu. Luminanční maska je bere z jasu maskovacího obsahu, takže bílá oblast je zcela neprůhledná a černá zcela průhledná. Luminance je ta, po které designéři sahají, protože namalování šedivého přechodu je přirozený způsob, jak popsat vytrácení

Formulářové měkké masky se staví ze zachyceného obsahu a několik detailů je pevně dané, ne volitelné. Zachycený obsah se stane izolovanou skupinou průhlednosti v DeviceRGB, takže se maska vyhodnocuje ve známém barevném prostoru. Barva pozadí proto musí mít tři komponenty, které odpovídají této skupině. Přenosová funkce přijímá /Identity nebo platný objekt funkce, což vám umožňuje přetvarovat křivku masky bez přemalování grafiky

Diagram porovnávající luminanční a alfa měkké masky zásobující NewSoftMaskGraphicsState, s připomínkou, že stav grafiky přetrvává, dokud se nevymaže
Luminanční masky čtou jas, zatímco alfa masky čtou krytí, a NewSoftMaskGraphicsState kteroukoli z nich zabalí do přetrvávajícího stavu grafiky
uses
  PDFlibrary;

var
  Lib: TPDFlib;
  MaskCapture, MaskGS, PhotoID: Integer;
begin
  Lib := TPDFlib.Create;
  try
    Lib.LoadFromFile('brochure.pdf', '');

    // Stránka 4 nese šedivý přechod namalovaný pro použití jako maska
    MaskCapture := Lib.CapturePage(4);

    MaskGS := Lib.NewSoftMaskGraphicsState(MaskCapture,
      PDF_SOFT_MASK_LUMINOSITY, '0 0 0', '/Identity');

    Lib.SelectPage(1);
    Lib.SetGraphicsState(MaskGS);
    PhotoID := Lib.AddImageFromFile('hero.jpg', 0);
    Lib.SelectImage(PhotoID);
    Lib.DrawImage(40, 700, 515, 260);        // vytrácí se pod maskou

    // Nastavení ExtGState přetrvávají: rozsah ukončete explicitně
    Lib.SetGraphicsState(Lib.NewSoftMaskGraphicsState(0,
      PDF_SOFT_MASK_NONE, '', ''));

    Lib.SaveToFile('brochure-masked.pdf');
  finally
    Lib.Free;
  end;
end;

Tento poslední krok není ozdoba. Parametry stavu grafiky přetrvávají, dokud se nezmění, a aplikace obyčejného stavu grafiky poté aktivní měkkou masku nevymaže. Bez explicitního /SMask /None zdědí vše nakreslené po maskované grafice tuto masku, což je jedna z matoucích chyb k vizuální diagnóze

Obrazové masky a položka Matte

Pro maskování na úrovni obrázku se maskovací obrázek nejdřív normalizuje do DeviceGray, takže se maska dodaná v jakémkoli barevném prostoru chová předvídatelně. Volitelná položka /Matte, jedna až čtyři komponenty podle barevného prostoru obrázku, sděluje spotřebiteli, že obrazová data jsou předvynásobena touto barvou, což zabraňuje tmavé svatozáři, jež se objeví, když se předvynásobená grafika skládá, jako by šlo o přímou alfu

Diagram znázorňující, jak chybějící položka Matte produkuje tmavé svatozáře, zatímco deklarovaná Matte skládá čistě, vedle ochranných mechanismů PDF 1.4 a PDF/A a PDF/X
Deklarovaná /Matte zabraňuje tmavé svatozáři předvynásobené grafiky, zatímco soubory PDF/A-1 a PDF/X-1 se odmítnou dřív, než se změní jakýkoli objekt

Zde mají význam dva ochranné mechanismy. PDF/A-1 a PDF/X-1 zakazují průhlednost a volání se odmítne dřív, než upraví jakýkoli objekt, místo aby vyprodukovalo soubor, který později selže při validaci. A úspěšná měkká maska vyžaduje PDF 1.4, což knihovna nastaví automaticky — průhlednost před touto verzí neexistovala a hlavička 1.3 na souboru obsahujícím měkké masky by byla prostě lživá

Opakované stavy se znovu použijí: stejný zachycený formulář, typ masky, pozadí a podpis přenosové funkce vyprodukují stejný objekt stavu grafiky místo nového pro každé volání. Na dokumentu, který maskuje sto obrázků identicky, je to devadesát devět objektů, které se nikdy nezapíšou

Proč zplošťovat a co zploštění skutečně dělá

Průhlednost je stále nejčastější zdroj problému "na obrazovce to vypadá správně a na tisku špatně". Starší RIP, některé regulatorní systémy pro podání a celé PDF/X-1a vyžadují soubor bez jakékoli živé průhlednosti

Zploštění je zde záměrně doslovné: každá stránka v požadovaném rozsahu se vykreslí ve zvoleném DPI na neprůhledném pozadí a obsah a zdroje stránky se nahradí tímto jedním obrázkem. Protože renderer vyprodukuje finální složený výsledek, toto pokrývá vše najednou — skupiny průhlednosti, režimy prolnutí, měkké masky, vzory a vnořené formuláře — bez jakékoli logiky přibližování jednotlivých konstrukcí, kterou by bylo možné zpackat. Špičková paměť pro rastr zůstává omezena na jednu stránku

Diagram pipeline FlattenTransparency vykreslující každou požadovanou stránku při 300 DPI na neprůhledném pozadí a ukládající plochý tiskově připravený soubor PDF 1.3
Každá požadovaná stránka se vykreslí jednou ve zvoleném DPI a vrátí se jako jeden neprůhledný obrázek uložený do pravdivého souboru PDF 1.3
// Zploštění stránek 1-8 při 300 DPI na bílém, pak uložení jako PDF 1.3
Lib.FlattenTransparency('1-8', 300, $FFFFFF, 0);
Lib.SaveToFile('press-ready.pdf');

Cena je stejně doslovná: výstupem je obrázek, takže text už není vybíratelný ani prohledávatelný a vektorové hrany se převzorkují ve zvoleném DPI. Zploštění je dodávací krok, ne úpravový krok. Ponechte si průhledný originál a zplošťujte kopii

Otočené stránky, uživatelské jednotky a rámce stránky

Otočená stránka vyžaduje péči, kterou naivní implementace přeskočí. Po vykreslení se vizuální šířka a výška zapíšou zpět do MediaBox, uživatelská jednotka se zapracuje do efektivního DPI a nové velikosti stránky a položka /Rotate, uživatelská jednotka a pomocné rámce stránky se odstraní

Vynechání tohoto vyprodukuje soubor, kde je zploštělý obrázek správný, ale prohlížeč ho znovu otočí, nebo ho zvětší uživatelskou jednotkou, která už neplatí. Odstranění rámců místo jejich přepočítání je správné rozhodnutí, protože TrimBox popisující geometrii před zploštěním je horší než žádný TrimBox vůbec

Anotace a pole formuláře se ve výchozím stavu vykreslí do statického obrázku a interaktivní objekty se odstraní, což je to, co chce tiskově připravená dodávka. Pokud interaktivní objekty ponecháte, vypne se anotační průchod rendereru, aby se nic nekreslilo dvakrát

Kontrola verze, která projde vším

Uložení jako PDF 1.3 vyžaduje, aby nikde nezůstala žádná průhlednost, a kontrola před uložením prochází každý nepřímý objekt, ne jen ty dosažitelné ze stránek. To je přísnější, než se na první pohled zdá, a je to správné: osiřelá měkká maska zanechaná dřívější úpravou je stále v souboru a spotřebitel, který prochází objekty místo stránek, ji najde

Aby bylo snížení verze dosažitelné, ve výchozím stavu proběhne po úspěšném nahrazení každé cílové stránky průchod mark-and-sweep, který uvolní nedosažitelné objekty. Důsledek, se kterým je třeba počítat, je, že identifikátory obrázku, zachycené stránky a stavu grafiky získané před tímto průchodem mohou být poté neplatné. Znovu si opatřete identifikátory zdrojů, které potřebujete, než budete pokračovat v úpravách, nebo tento průchod vypněte a smiřte se s tím, že verzi pak nelze snížit

Obraz doplňují dva společníci. Vektorovou grafiku, která používá stínování a přechody místo masek, popisuje článek vektorová grafika, shadery a přechody, a bývá to lepší cesta, když lze efekt vyjádřit jako stínování. A pokud je důvodem zploštění barevný požadavek, ne požadavek na průhlednost, cesta konverze v článku převod barevného prostoru dokumentu zachová živý text tam, kde by zploštění nezachovalo

Vytváření měkkých masek, zploštění a vykreslovací engine za nimi jsou dodávány v jedné knihovně pro Delphi, C++Builder a Free Pascal; úplný seznam funkcí najdete na stránce PDF Library for Delphi