Transparenz

PDF 1.4 führt ein echtes Transparenzmodell ein. Dabei können die einzelnen Punkte nicht nur durchsichtig oder undurchsichtig, sondern auch halbdurchsichtig sein. Dies ist einerseits nützlich, wenn man Bilder mit Alphakanal einbinden will. Zum anderen lassen sich damit Effekte erreichen, die übereinander gestapelten Projektorfolien ähneln.

Wie schon fast üblich, wenn Adobe ein neues Feature einführt, ist dieses sehr umfassend und komplex. Ich mache hier darum nur eine Einführung für die häufigsten Anwendungen:

Bilder

Für eingebundene Bilder kann die Transparenz auf zwei Arten definiert werden: Über einen Alphakanal, der die Transparenz jedes Bildpunkts einzeln festlegt, oder indem eine Farbe (bzw. ein Farbbereich) als Transparent definiert wird.

Alphakanal

Ein Alphakanal ist ein zweites Bild mit derselben Auflösung, wie das eigentliche Bild. Dabei muss es sich um ein Graustufenbild handeln. Je heller ein Bildpunkt ist, desto undurchsichtiger ist der entsprechende Bildpunkt im eigentlichen Bild. Weiss steht folglich für völlig undurchsichtig, Schwarz für völlig durchsichtig.

Bilder im PNG Format können einen Alphakanal enthalten. Leider ist dieser aber nicht als separates Bild abgelegt, sondern eingebettet in die normalen Bilddaten. Daher muss das Bild dekodiert, und die Farbinformationen von den Transparenzinformationen getrennt werden. Für diesen Zweck stehen für praktisch alle Programmiersprachen entsprechende Bibliotheken zur Verfügung.

Um den Alphakanal in PDF verwenden zu können, wird er über ein ganz normales Bildobjekt eingebunden. Dieses muss zwingend den Farbraum /DeviceGray verwenden. Das Bild mit dem Alphakanal muss nicht im Resourcendictionary vermerkt werden. Im Dictionary des eigentlichen Bild gibt es einen zusätzlichen Eintrag /SMask mit eine Referenz auf den Alphakanal.

Beispiel:

10 0 obj
<<
/Type /XObject
/Subtype /Image
/Width 800
/Height 600
/ColorSpace /DeviceRGB
/BitsPerComponent 8
/SMask 11 0 R
/Filter [/ASCII85Decode /FlateDecode]
/Length 461808
>>
stream
...~>
endstream
endobj

11 0 obj
<<
/Type /XObject
/Subtype /Image
/Width 800
/Height 600
/ColorSpace /DeviceGray
/BitsPerComponent 8
/Filter [/ASCII85Decode /FlateDecode]
/Length 153936
>>
stream
...~>
endstream
endobj

transparente Farbe

Man kann eine Farbe oder ein Farbbereich kann als transparent definieren. Dazu muss im Dictionary des Bildes ein Eintrag /Mask angegeben werden. Der Wert definiert sich folgendermassen:

Bei den „normalen“ Farbräumen /DeviceGray, /DeviceRGB und /DeviceCMYK muss ein Array mit zwei Einträgen pro Farbkomponente angegeben werden. Sind die beiden Werte der Farbkomponente identisch, so definieren sie genau diese Intensität. Sind sie unterschiedlich, so definieren sie ein Intensitätsbereich vom ersten bis zum zweiten Wert (der erste Wert muss die kleinere Zahl sein). Im Array müssen die beiden Werte pro Komponente jeweils nacheinander stehen. Die Komponenten selbst sind in der üblichen, durch die Abkürzung angedeuteten Reihenfolge.

Beispiel:

/ColorSpace /DeviceRGB
/Mask [0 0 0 0 1 1]

Dies definiert volles Blau als transparent.

Bei /Indexed Farbräumen muss ein Array mit genau zwei Werten angegeben werden. Sind beide identisch, so definieren sie die entsprechende Farbe der Palette. Sind sie unterschiedlich, so definieren sie einen Bereich aus der Palette vom ersten zum zweiten Wert (der erste Wert muss die kleinere Zahl sein). In beiden Fällen sind die Farben in der Palette von Null an durchnummeriert.

Beispiel:

/ColorSpace [/Indexed /DeviceRGB 3 <FF000000FF000000FFFFFFFF>]
/Mask [3 3]

Dies definert die Farbe Nummer 3 (die vierte in der Palette) als transparent.

Vektorgrafik

Wir können sowohl die Linienfarbe wie auch die Füllfarbe als halbtransparent definieren (oder auch völlig transparent, aber das macht wenig Sinn). Leider stellt uns PDF dafür aber keine Anweisungen zur Verfügung. Wir müssen auf den umständlicheren Mechanismus für erweiterte grafische Parameter zurückgreifen.

Zu diesem Zweck erhält das Resourcendictionary ein weiteres Unterdictionary namens /ExtGState. In diesem können wir beliebig viele Einträge anlegen. Als Name wird dabei typischerweise /GS gefolgt von einer Nummer gewählt. Der Wert ist jeweils ein Unterdictionary, welches in unserem Fall ein oder zwei Einträge haben kann. Einen Eintrag /CA für die Linienfarbe, und einen Eintrag /ca für die Füllfarbe. Der Wert ist jeweils eine Zahl von 0 - 1, wobei 0 für völlig durchsichtig, 1 für völlig undurchsichtig, und ein Dezimalbruch dazwischen für dem Wert entsprechend halbdurchsichtig steht.

Beispiel:

/ExtGState << /GS1 << /CA 0.8 /ca 0.5 >> >>

Damit legen wir einen erweiterten Parameter fest, welcher die Linienfarbe auf 80% deckend, die Füllfarbe auf 50% deckend einstellt.

Um den Parameter nun in der Seite oder Form anzuwenden, benötigen wir eine neue Anweisung gs. Die Anweisung erwartet als Parameter den Namen aus /ExtGState.

Beispiel:

0.5 G
0 0.75 0.75 rg
/GS1 gs
100 100 150 150 re b

Bilder und Muster

Die Transparenz der Füllfarbe wird auch auf Bilder angewendet. Verfügt das Bild über eigene Transparenz, so ist der Effekt kumulativ.

Die Transparenz der Füllfarbe wirkt auch auf Muster. Dies (im Unterschied zu allen anderen Anweisungen) unabhängig davon, ob das Muster innerhalb derselben Seite oder Form verwendet wird, in der die Transparenz gesetzt wurde, oder in einer eingebundenen Form. Allerdings wird bei Kachelmustern erst der Inhalt der Kachel ohne Transparenz gerechnet1), und das Resultat dann transparent gemacht.

1) ausser man setzt Transparenz innerhalb des Musters