Neben den bereits innerhalb der Kapitel erwähnten Tricks gibt es noch ein paar Kniffe, mit denen wir unser PDF verkleinern können. Wenn wir diese alle befolgen, ist das Dokument aber nicht mehr richtig in einem Texteditor betrachtbar, und die Anweisungen können auch nicht mehr „von Hand“ entziffert werden. Darum sollte man die Massnahmen erst einschalten, wenn man sich sicher ist, dass die Dokumente korrekt erzeugt werden.
Wenn wir beim Schreiben des PDFs den Binärmodus aktivieren, so erreichen wir damit unter Windows direkt eine Einsparung. Es wird dann nämlich für den Zeilenumbruch nicht der vom Betriebsystem vorgegebene Code verwendet, sondern jener der internen Darstellung. Der Windows-Zeilenumbruch ist 2 Byte lang. Die interne Darstellung verwendet meist den UNIX-Zeilenumbruch, der nur 1 Byte lang ist.
Aufpassen muss man allerdings bei der Referenztabelle am Ende des Dokuments. Deren Zeilen müssen bekanntlich samt Zeilenumbruch immer genau 20 Byte lang sein. Darum muss dort zwischen dem Buchstaben (n oder f) und dem Zeilenumbruch ein Leerzeichen eingefügt werden, sofern der Zeilenumbruch nur 1 Byte lang ist.
Auf anderen Systemen als Windows wird das Schreiben der Dateien im Binärmodus keine direkten Einsparungen bringen. Bei manchen Programmiersprachen ist es aber eine Voraussetzung, um Daten binär zu schreiben.
Streams mit binären Daten haben wir bisher mittels ASCII85 (oder per Hexadezimalschreibweise) in eine Abfolge von ASCII-Zeichen umgewandelt. Wenn wir darauf verzichten, und die Daten direkt in den Stream schreiben, kommen wir natürlich mit weniger Bytes aus. Die Vorgehensweise ist schon im Kapitel über Binäre Streams erklärt.
Verschiedentlich sind die Daten, die wir in einen Stream schreiben, bereits komprimiert. Manchmal ist dies aber nicht der Fall. Insbesondere die Streams mit dem Seiteninhalt sind komplett unkomprimiert. Hier können wir die Daten selbst komprimieren, um die Datei so zu verkleinern.
Für die meisten Programmiersprachen ist eine Implementation des Deflate Kompressionsalgorithmus erhältlich. Am bekanntesten ist wohl zlib, welches in C geschrieben, aber auch von vielen, anderen Sprachen aus nutzbar ist.
In den Stream schreiben wir einfach statt der unkomprimierten Daten die mit Deflate komprimierten Daten. Dementsprechend muss natürlich der /FlateDecode
Filter aktiviert werden.
Hinweis: Nicht alle Daten lassen sich gut komprimieren. Unter Umständen ist die komprimierte Version sogar grösser, als das Original. Es empfiehlt sich daher, nach der Kompression die Grössen zu vergleichen, und allenfalls beim Original zu bleiben.
An einigen Stellen haben wir Hexstrings verwendet, namentlich für Texte bei symbolischen Schriften und die Palette bei indizierten Farbräumen. Man kann aber auch normale Strings verwenden, und die Daten in binärer Form belassen.
Wie bei normalen Textstrings müssen wir den im String enthaltenen runden Klammern und Backslashes einen Backslash voranstellen. Bei binären Daten müssen wir dementsprechend vor Bytes, deren Wert dem ASCII-Code von runden Klammern oder einem Backslash entspricht, ein Byte mit dem ASCII-Code eines Backslashes einfügen. Auch hier gilt, dass Paare aus einer öffnenden und einer folgenden geschlossenen runden Klammer keinen Backslash benötigen. Die Codes sind:
Zeichen | Code |
---|---|
( | 0x28 |
) | 0x29 |
\ | 0x5C |
Zusätzlich müssen auch Bytes mit dem Wert 0x0A oder 0x0D umgeschrieben werden. Dies sind in ASCII die Steuerzeichen für Zeilenumbruch, und manche Programme „übersetzen“ solche automatisch in die interne Darstellung von Zeilenumbrüchen. 0x0A muss ersetzt werden durch den ASCII-String \n
(<5C 6E>), 0x0D durch den ASCII-String \r
(<5C 72>).
Im Kapitel Syntax habe ich geschrieben, dass Objekte immer durch Leerräume getrennt sein sollten. Tatsächlich ist es aber oft nicht zwingend nötig. Ist von der Syntax her klar, dass ein neues Objekt beginnt, so kann auf den Leerraum verzichtet werden. Grundsätzlich gilt:
Diskussion