Technischer Artikel

Weiche Masken und Transparenz-Flattening in Delphi

PDF Library for Delphi erstellt aus Delphi beide Arten von PDF-Softmasken. SetImageSoftMaskEx hängt ein Maskenbild an ein Zielbild an und kann den /Matte-Eintrag schreiben, den vormultiplizierte Grafik benötigt. NewSoftMaskGraphicsState baut aus erfasstem Inhalt eine Alpha- oder Luminanzmaske und liefert einen Grafikzustand zurück, den Sie auf nachfolgendes Zeichnen anwenden. Und wenn ein Konsument Transparenz überhaupt nicht handhaben kann, rendert FlattenTransparency das visuelle Ergebnis und ersetzt jede Seite dadurch

Softmasken sind der Weg, auf dem PDF eine Verlaufsüberblendung, eine Vignette, ein in einen Hintergrund eingeblendetes Foto und jeden anderen Effekt ausdrückt, bei dem die Deckkraft über einen Bereich variiert. Konstante Transparenz ist eine einzelne Zahl im Grafikzustand; eine Softmaske ist eine ganze Funktion der Position, und solange Sie keine erstellen können, lässt sich eine ganze Designkategorie nicht reproduzieren

Die zwei Maskentypen, und was jeder liest

Eine Alpha-Maske nimmt ihre Werte aus dem Alphakanal des maskierenden Inhalts. Eine Luminanzmaske nimmt sie aus der Helligkeit des maskierenden Inhalts, sodass ein weißer Bereich vollständig deckend und ein schwarzer Bereich vollständig transparent ist. Luminanz ist diejenige, zu der Designer greifen, denn einen Graustufenverlauf zu malen ist ein natürlicher Weg, eine Überblendung zu beschreiben

Formular-Softmasken werden aus erfasstem Inhalt gebaut, und mehrere Details sind festgelegt statt optional. Der erfasste Inhalt wird zu einer isolierten Transparenzgruppe in DeviceRGB, sodass die Maske in einem bekannten Farbraum ausgewertet wird. Die Hintergrundfarbe muss daher drei Komponenten haben, passend zu dieser Gruppe. Die Übertragungsfunktion akzeptiert /Identity oder ein gültiges Funktionsobjekt, was es erlaubt, die Maskenkurve umzuformen, ohne die Grafik neu zu malen

Diagramm, das Luminanz- und Alpha-Softmasken vergleicht, die in NewSoftMaskGraphicsState einfließen, mit dem Hinweis, dass der Grafikzustand bestehen bleibt, bis er gelöscht wird
Luminanzmasken lesen die Helligkeit, während Alphamasken die Deckung lesen, und NewSoftMaskGraphicsState verpackt beide in einem bestehenden Grafikzustand
uses
  PDFlibrary;

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

    // Seite 4 enthält einen zur Verwendung als Maske gemalten Graustufenverlauf
    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);        // blendet unter der Maske aus

    // ExtGState-Einstellungen bleiben bestehen: den Geltungsbereich explizit beenden
    Lib.SetGraphicsState(Lib.NewSoftMaskGraphicsState(0,
      PDF_SOFT_MASK_NONE, '', ''));

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

Dieser letzte Schritt ist keine Dekoration. Grafikzustandsparameter bleiben bestehen, bis sie geändert werden, und das nachträgliche Anwenden eines gewöhnlichen Grafikzustands löscht keine aktive Softmaske. Ohne ein explizites /SMask /None erbt alles, was nach der maskierten Grafik gezeichnet wird, die Maske, was einer der verwirrenderen Fehler ist, die sich visuell diagnostizieren lassen

Bildmasken und der Matte-Eintrag

Für Maskierung auf Bildebene wird das Maskenbild zunächst auf DeviceGray normalisiert, sodass sich eine in beliebigem Farbraum gelieferte Maske vorhersehbar verhält. Der optionale /Matte-Eintrag, ein bis vier Komponenten je nach Farbraum des Bilds, teilt einem Konsumenten mit, dass die Bilddaten gegen diese Farbe vormultipliziert sind, was den dunklen Rand verhindert, der auftritt, wenn vormultiplizierte Grafik so zusammengesetzt wird, als wäre sie einfaches Alpha

Diagramm, das zeigt, wie ein fehlender Matte-Eintrag dunkle Ränder erzeugt, während ein deklarierter Matte-Eintrag sauber zusammensetzt, daneben die Schutzmechanismen für PDF 1.4 sowie PDF/A und PDF/X
Ein deklarierter /Matte-Eintrag verhindert den dunklen Rand vormultiplizierter Grafik, während PDF/A-1- und PDF/X-1-Dateien verweigert werden, bevor irgendein Objekt geändert wird

Zwei Schutzmechanismen sind hier wichtig. PDF/A-1 und PDF/X-1 verbieten Transparenz, und der Aufruf verweigert, bevor irgendein Objekt geändert wird, statt eine Datei zu erzeugen, die später die Validierung nicht besteht. Und eine erfolgreiche Softmaske erfordert PDF 1.4, was die Bibliothek automatisch setzt — Transparenz existierte vor dieser Version nicht, und ein 1.3-Header auf einer Datei mit Softmasken ist schlicht falsch

Wiederholte Zustände werden wiederverwendet: Dieselbe Signatur aus erfasstem Formular, Maskentyp, Hintergrund und Übertragungsfunktion liefert dasselbe Grafikzustandsobjekt statt eines neuen pro Aufruf. Bei einem Dokument, das hundert Bilder identisch maskiert, sind das neunundneunzig Objekte, die nie geschrieben werden

Warum abflachen, und was das Abflachen tatsächlich tut

Transparenz ist immer noch die häufigste Quelle für „sieht am Bildschirm richtig aus und in der Druckerei falsch“. Ältere RIPs, manche behördlichen Einreichungssysteme und PDF/X-1a erfordern allesamt eine Datei ganz ohne lebende Transparenz

Das Abflachen ist hier bewusst wörtlich gemeint: Jede Seite im angeforderten Bereich wird mit einer gewählten DPI gegen einen deckenden Hintergrund gerendert, und Seiteninhalt und -ressourcen werden durch dieses eine Bild ersetzt. Da der Renderer das endgültige zusammengesetzte Ergebnis erzeugt, deckt dies alles auf einmal ab — Transparenzgruppen, Blend-Modi, Softmasken, Muster und verschachtelte Formulare — ohne Näherungslogik pro Konstrukt, die falsch sein könnte. Der Spitzenverbrauch an Rasterspeicher bleibt auf eine Seite begrenzt

Pipeline-Diagramm von FlattenTransparency, das jede angeforderte Seite mit 300 DPI auf deckendem Hintergrund rendert und eine flache druckfertige PDF-1.3-Datei speichert
Jede angeforderte Seite wird einmal mit der gewählten DPI gerendert und kommt als einzelnes deckendes Bild zurück, gespeichert in einer wahrheitsgemäßen PDF-1.3-Datei
// Seiten 1-8 mit 300 DPI auf Weiß abflachen, dann als PDF 1.3 speichern
Lib.FlattenTransparency('1-8', 300, $FFFFFF, 0);
Lib.SaveToFile('press-ready.pdf');

Der Kompromiss ist ebenso wörtlich: Die Ausgabe ist ein Bild, sodass Text nicht mehr selektierbar oder durchsuchbar ist und Vektorkanten mit der gewählten DPI neu abgetastet werden. Abflachen ist ein Auslieferungsschritt, kein Bearbeitungsschritt. Bewahren Sie das transparente Original auf und flachen Sie eine Kopie ab

Gedrehte Seiten, Benutzereinheiten und die Seitenboxen

Eine gedrehte Seite erfordert Sorgfalt, die eine naive Implementierung überspringt. Nach dem Rendern werden die visuelle Breite und Höhe in die MediaBox zurückgeschrieben, die Benutzereinheit wird in die effektive DPI und die neue Seitengröße eingerechnet, und der /Rotate-Eintrag, die Benutzereinheit und die zusätzlichen Seitenboxen werden entfernt

Das zu überspringen erzeugt eine Datei, bei der das abgeflachte Bild korrekt ist, ein Betrachter es aber erneut dreht oder mit einer Benutzereinheit skaliert, die nicht mehr gilt. Die Boxen zu entfernen statt sie neu zu berechnen ist die richtige Entscheidung, denn eine TrimBox, die die Geometrie vor dem Abflachen beschreibt, ist schlimmer als gar keine TrimBox

Annotationen und Formularfelder werden standardmäßig in das statische Bild gerendert und die interaktiven Objekte entfernt, was ein druckfertiges Liefergut möchte. Behalten Sie stattdessen die interaktiven Objekte, wird der Annotations-Durchlauf des Renderers abgeschaltet, damit nichts doppelt gezeichnet wird

Die Versionsprüfung, die alles scannt

Das Speichern als PDF 1.3 erfordert, dass nirgends noch Transparenz übrig bleibt, und die Prüfung vor dem Speichern untersucht jedes indirekte Objekt, nicht nur die von Seiten aus erreichbaren. Das ist strenger, als es zunächst wirkt, und es ist richtig: Eine von einer früheren Bearbeitung zurückgelassene verwaiste Softmaske befindet sich noch in der Datei, und ein Konsument, der Objekte statt Seiten durchläuft, wird sie finden

Um das Herabstufen erreichbar zu machen, läuft standardmäßig ein Mark-and-Sweep-Durchlauf, sobald jede Zielseite erfolgreich ersetzt wurde, und gibt die unerreichbaren Objekte frei. Die Konsequenz, die Sie einplanen sollten: Bild-, erfasste-Seite- und Grafikzustandskennungen, die vor diesem Sweep erhalten wurden, sind danach möglicherweise nicht mehr gültig. Beschaffen Sie die benötigten Ressourcenkennungen neu, bevor Sie weiter bearbeiten, oder deaktivieren Sie den Sweep und akzeptieren Sie, dass die Version dann nicht herabgesetzt werden kann

Zwei Begleiter vervollständigen das Bild. Vektorgrafik, die Shadings und Verläufe statt Masken verwendet, ist unter Vektorgrafik, Shader und Verläufe behandelt, und das ist oft der bessere Weg, wenn sich der Effekt als Shading ausdrücken lässt. Und wenn der Grund für das Abflachen eine Farbanforderung statt einer Transparenzanforderung ist, bewahrt der Umrechnungspfad unter Umfärben eines Dokuments in einen anderen Farbraum lebenden Text, wo Abflachen das nicht täte

Softmasken-Erstellung, Abflachen und die dahinterliegende Rendering-Engine werden in einer Bibliothek für Delphi, C++Builder und Free Pascal ausgeliefert; die vollständige Funktionsliste finden Sie auf der Seite der PDF Library for Delphi