PDF Library for Delphi skapar båda typerna av PDF-mjuka masker från Delphi. SetImageSoftMaskEx kopplar en maskbild till en målbild och kan skriva den /Matte-post som förmultiplicerad grafik behöver. NewSoftMaskGraphicsState bygger en alfa- eller luminansmask från fångat innehåll och returnerar ett grafiktillstånd du tillämpar på efterföljande ritning. Och när en konsument inte kan hantera transparens alls, renderar FlattenTransparency det visuella resultatet och ersätter varje sida med det
Mjuka masker är hur PDF uttrycker en gradienttoning, en vinjett, ett foto blandat in i en bakgrund, och varje annan effekt där opaciteten varierar över en region. Konstant transparens är ett enda tal i grafiktillståndet; en mjuk mask är en hel funktion av position, och tills du kan skapa en sådan kan en hel kategori av design inte återskapas
De två masktyperna, och vad var och en läser
En alfamask tar sina värden från alfakanalen i det maskerande innehållet. En luminansmask tar dem från ljusheten i det maskerande innehållet, så en vit yta är helt opak och en svart yta helt transparent. Luminans är den designers tar till, eftersom att måla en gråskalegradient är ett naturligt sätt att beskriva en toning
Formbaserade mjuka masker byggs från fångat innehåll, och flera detaljer är fasta snarare än valfria. Det fångade innehållet blir en isolerad transparensgrupp i DeviceRGB, så masken utvärderas i en känd färgrymd. Bakgrundsfärgen måste därför ha tre komponenter, i linje med den gruppen. Överföringsfunktionen accepterar /Identity eller ett giltigt funktionsobjekt, vilket låter dig omforma maskkurvan utan att måla om grafiken
uses
PDFlibrary;
var
Lib: TPDFlib;
MaskCapture, MaskGS, PhotoID: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.LoadFromFile('brochure.pdf', '');
// Sida 4 innehåller en gråskalegradient målad för att användas som mask
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); // tonas bort under masken
// ExtGState-inställningar kvarstår: avsluta scopet explicit
Lib.SetGraphicsState(Lib.NewSoftMaskGraphicsState(0,
PDF_SOFT_MASK_NONE, '', ''));
Lib.SaveToFile('brochure-masked.pdf');
finally
Lib.Free;
end;
end;
Det sista steget är inte dekoration. Grafiktillståndsparametrar kvarstår tills de ändras, och att tillämpa ett vanligt grafiktillstånd efteråt rensar inte en aktiv mjuk mask. Utan ett explicit /SMask /None ärver allt som ritas efter den maskerade grafiken masken, vilket är en av de mer förbryllande buggarna att diagnostisera visuellt
Bildmasker och Matte-posten
För maskning på bildnivå normaliseras maskbilden till DeviceGray först, så en mask som tillhandahålls i vilken färgrymd som helst beter sig förutsägbart. Den valfria /Matte-posten, en till fyra komponenter beroende på bildens färgrymd, talar om för en konsument att bilddatan är förmultiplicerad mot den färgen, vilket förhindrar den mörka halo som uppstår när förmultiplicerad grafik sammansätts som om den vore rak alfa
Två skyddsräcken spelar roll här. PDF/A-1 och PDF/X-1 förbjuder transparens, och anropet avvisar innan något objekt ändras snarare än att producera en fil som misslyckas i validering senare. Och en lyckad mjuk mask kräver PDF 1.4, vilket biblioteket sätter automatiskt — transparens fanns inte före den versionen, och ett 1.3-huvud på en fil som innehåller mjuka masker är helt enkelt falskt
Upprepade tillstånd återanvänds: samma fångade formulär, masktyp, bakgrund och överföringsfunktionssignatur ger samma grafiktillståndsobjekt snarare än ett nytt per anrop. På ett dokument som maskerar hundra bilder identiskt är det nittionio objekt som aldrig skrivs
Varför platta till, och vad plattning faktiskt gör
Transparens är fortfarande den vanligaste källan till "det ser rätt ut på skärmen och fel i trycket". Äldre RIP:ar, vissa regulatoriska inlämningssystem och PDF/X-1a kräver alla en fil helt utan levande transparens
Plattning här är avsiktligt bokstavlig: varje sida i det begärda intervallet renderas vid en vald DPI mot en opak bakgrund, och sidans innehåll och resurser ersätts av den enda bilden. Eftersom renderaren producerar det slutliga sammansatta resultatet täcker detta allt på en gång — transparensgrupper, blandningslägen, mjuka masker, mönster och nästlade formulär — utan någon per-konstruktions-approximationslogik som kan bli fel. Toppminnesanvändningen för rastrering hålls begränsad till en sida
// Platta till sidorna 1-8 vid 300 DPI på vitt, spara sedan som PDF 1.3
Lib.FlattenTransparency('1-8', 300, $FFFFFF, 0);
Lib.SaveToFile('press-ready.pdf');
Priset är lika bokstavligt: utdatan är en bild, så text är inte längre markerbar eller sökbar och vektorkanter samplas om vid den valda DPI:n. Plattning är ett leveranssteg, inte ett redigeringssteg. Behåll det transparenta originalet och platta till en kopia
Roterade sidor, användarenheter och siduterna
En roterad sida behöver omsorg en naiv implementation hoppar över. Efter rendering skrivs den visuella bredden och höjden tillbaka till MediaBox, användarenheten fälls in i den effektiva DPI:n och den nya sidstorleken, och posten /Rotate, användarenheten och de extra siduterna tas bort
Att hoppa över det ger en fil där den tillplattade bilden är korrekt men en visare roterar den igen, eller skalar den efter en användarenhet som inte längre gäller. Att ta bort siduterna snarare än att omberäkna dem är rätt beslut, eftersom en TrimBox som beskriver geometrin innan plattning är värre än ingen TrimBox alls
Annoteringar och formulärfält renderas som standard in i den statiska bilden och de interaktiva objekten tas bort, vilket är vad en tryckklar leverans vill ha. Om du behåller de interaktiva objekten istället stängs renderarens annoteringspassering av så att inget ritas två gånger
Versionskontrollen som skannar allt
Att spara som PDF 1.3 kräver att ingen transparens kvarstår någonstans, och kontrollen innan sparning granskar varje indirekt objekt, inte bara de som nås från sidor. Det är strängare än det först verkar och det är korrekt: en föräldralös mjuk mask som lämnats kvar av en tidigare redigering finns fortfarande i filen, och en konsument som går igenom objekt snarare än sidor kommer att hitta den
För att göra nedgraderingen genomförbar körs som standard en mark-and-sweep-passering så snart varje målsida har ersatts framgångsrikt, vilket frigör de oåtkomliga objekten. Konsekvensen att planera för är att identifierare för bild, fångad sida och grafiktillstånd som erhållits före den sopningen kanske inte längre är giltiga efteråt. Hämta de resursidentifierare du behöver på nytt innan du fortsätter redigera, eller inaktivera sopningen och acceptera att versionen då inte kan sänkas
Två följeslagare fullbordar bilden. Vektorgrafik som använder skuggningar och gradienter snarare än masker täcks i vektorgrafik, shaders och gradienter, och det är ofta den bättre vägen när effekten kan uttryckas som en skuggning. Och om anledningen till att du plattar till är ett färgkrav snarare än ett transparenskrav, bevarar konverteringsvägen i omfärgning av ett dokument till en annan färgrymd levande text där plattning inte skulle göra det
Skapande av mjuka masker, plattning och renderingsmotorn bakom dem levereras i ett bibliotek för Delphi, C++Builder och Free Pascal; den fullständiga funktionslistan finns på sidan för PDF Library for Delphi