Das PNG-Format – der Guide für ein perfektes Ergebnis
Schaut euch diese beiden Bälle-Bilder an:
Sie sehen gleich aus, haben die gleiche Breite und Höhe, beide sind PNG. Dennoch unterscheidet sich die Dateigröße deutlich. Warum? Das kläre ich im Laufe dieses Textes – zusätzlich gebe ich euch fünf praktische Tipps zum Thema PNG-Kompression mit an die Hand.
Farbtiefen
Im Normalfall werden eure Bilder im RGB-Farbmodell vorliegen, genau wie unser Beispielbild. Ein Pixel besteht aus den Farbkanälen Rot, Grün und Blau – mit jeweils 256 Abstufungen. Warum 256? Weil sich jede Farbe eines Pixels über den Speicherverbrauch von einem Byte darstellen lassen soll. Und mit einem Byte lassen sich exakt 256 Werte ausdrücken. Mit einem Speicherverbrauch von drei Byte gebt ihr somit ein gesamtes Pixel wieder – jeweils ein Byte für Rot, Grün und Blau.
Ein Bild mit 800 x 600 Pixel ergibt somit einen Speicherverbrauch von 800 x 600 x 3 Byte = 1,44 Megabyte. Das entspricht ziemlich genau der Größe eines unkomprimierten BMP-Bildes (und lustigerweise einer 3,5-Zoll-HD-Diskette).
Dennoch sprechen wir nicht von einem Drei-Byte-Bild. Grund ist, dass es noch weitere Farbtiefen mit mehr als einem Byte pro Kanal gibt. Deshalb hat sich die Bezeichnung 24-Bit-Bild eingebürgert. Die 24 Bit ergeben sich, weil ein Byte aus acht Bits besteht. 3 x 8=24! Die Farbtiefe bezeichnet also den Speicherverbrauch eines Pixels.
32-Bit und Acht-Bit-Farbtiefen
Ein 32-Bit-PNG gleicht einem 24-Bit-PNG, enthält aber noch einen zusätzlichen Acht-Bit-Kanal für Transparenz (Alphakanal genannt). Somit kann es auch transparente Bereiche in 256 Abstufungen beinhalten.
Ein Acht-Bit-PNG funktioniert ein wenig anders: Hier werden bis zu 256 Farben mit ihren Rot-, Grün-, Blau- und Transparenz-Informationen in einer sogenannten „Palette“ festgelegt. Für jedes Pixel wird lediglich definiert, an welcher Stelle der Palette die entsprechende Farbe steht. Somit braucht ihr zum Speichern eines Pixels nur noch ein Byte an Speicher statt drei. Bei acht Bit seid ihr zwar auf maximal 256 Farben beschränkt, das sollte aber für die meisten Bilder im Web-Umfeld genügen.
Die Farbtiefe ist übrigens der erste Grund, warum sich die beiden Bälle-Beispielbilder in der Dateigröße unterscheiden. Das erste, kleinere PNG ist ein Acht-Bit-PNG, während das größere PNG ein 32-Bit-PNG ist.
8-Bit-PNG | 24-Bit-PNG | 32-Bit-PNG |
---|---|---|
Paletten-Bild | RGB-Bild | RGBA-Bild |
maximal 256 Farben | 16,8 Millionen Farben | 16,8 Millionen Farben + Transparenz |
Die Kompression
Ein PNG wird in drei Schritten komprimiert: vorfiltern, wörterbuch-basierte Kodierung per LZ77 und schließlich Häufigkeits-Kodierung, auch Entropiekodierung genannt.
Schritt 1: Das Vorfiltern
Daten können effizienter komprimiert werden, wenn sie sich möglichst oft wiederholen. Der Schritt des Vorfilterns versucht deshalb, aus unterschiedlichen Daten möglichst gleichartige zu generieren. Schauen wir uns mal die Rotwerte eines fünf mal fünf Pixel großen, gleichmäßigen Farbverlaufs an:
Auf jede Zeile wird ein Filter angewendet. In diesem Fall der Sub-Filter (Subtraktion). Der besagt, dass wir uns einfach nur die Differenz zum vorangegangenen Wert in der aktuellen Zeile merken. Dieser Schritt ist reversibel, sodass keine Daten verlorengehen. Wir müssen uns lediglich den angewendeten Filter pro Zeile merken. Unsere zu speichernden Werte sehen jetzt wie folgt aus und sind – dank des gleichmäßigen Farbverlaufs – sehr viel besser zu komprimieren:
Den optimalen Filter für eine Zeile herauszufinden (neben dem Sub gibt es noch vier weitere), ist eine Wissenschaft für sich. Aus Performancegründen schätzen Programme die beste Wahl aufgrund von Erfahrungswerten. Das klappt mal besser, mal schlechter. Ihr macht es den Filtern einfacher, wenn ihr Bilder entsprechend vorbereitet.
Habt ihr beispielsweise eine schwarze Fläche, die eigentlich gar nicht rein schwarz ist, sondern aus vielen fast-schwarzen Pixeln besteht, ist das äußerst nachteilig für die Kompression. Bereinigt ganz einfach diesen Zustand, indem ihr allen den gleichen Schwarzwert gebt. Für euer Auge entsteht kein Unterschied, für die Dateigröße ein sehr großer!
Schritt 2: Wörterbuch-basierte Kodierung per LZ77
LZ77 ist ein verlustfreies Verfahren, das sich wiederholende Sequenzen von Daten sucht. Trifft der Algorithmus auf eine Datensequenz, die er schon weiter vorne in einer Datei gesehen hat, ersetzt er diese mit einem Hinweis auf die erste Sequenz.
Kurz: Habt ihr gleiche Abbildungen von Objekten in einer PNG-Datei, belegt nur die erste Darstellung Platz. Die anderen werden euch praktisch geschenkt.
Hilfreich fürs Verständnis ist die „Compression-View“, die ihr meines Wissens nach lediglich hier findet, nachdem ihr ein PNG hochgeladen habt. Diese Ansicht zeigt euch, wie viel Speicher für einen bestimmten Bildbereich benötigt wird. Dunkelblau belegt praktisch keinen, Hellblau ein wenig, Gelb etwas mehr und Rot ziemlich viel Speicherplatz.
Im ersten Bild kostet nur das erste Auftreten der farbigen Bälle Speicherplatz. Alle anderen wurden euch geschenkt. Im zweiten sehen zwar eigentlich alle Bälle gleich aus, durch leichtes Bildrauschen gleicht aber kein Ball dem anderen. Deshalb wird jeder Ball einzeln gespeichert.
Vorsicht vor dem rutschenden Fenster
Ist euch ein Fehler aufgefallen? Warum belegt im ersten Bild der dritte rote Ball Speicherplatz, obwohl doch vorher schon zwei identische vorhanden sind?
Bei der Spezifikation des PNGs wurde aus Performance-Gründen ein Sliding-Window von 32 Kilobyte festgelegt. Verständlich ausgedrückt: Es wird nur in den vorherigen circa 32.000 Zeichen überprüft, ob eine bestimmte Sequenz bereits aufgetreten ist. Demnach gilt: Ist der Abstand zwischen zwei Objekten zu groß, wird nicht erkannt, dass sie gleich sind – und werden einzeln gespeichert.
Baut ihr eine „Brücke“ aus einem weiteren roten Ball an der richtigen Stelle, verschwindet der dritte aus der Compression-View und die Datei wird folgerichtig noch kleiner:
Schritt 3: Entropiekodierung
Dies ist der letzte Schritt der PNG-Kompression. Hier wird versucht, jedes Zeichen mit einer möglichst kleinen Bitfolge darzustellen. Das trägt jedoch nichts zum allgemeinen Verständnis des PNG-Formats bei.
5 Tricks zur Verringerung der Dateigröße
Wie versprochen bekommt ihr noch fünf praktische Tipps, die euch möglichst viel Dateigröße einsparen können.
1. Nur Original-Daten komprimieren
Achtet darauf, immer die Original-Daten zu komprimieren.
Das Ursprungsbild ist hier ein JPG. Dieser Bild-Kompressions-Algorithmus hat Artefakte erzeugt, die für die PNG-Kompression „tödlich“ sind. Es sind Unmengen an Farben und Bildmustern entstanden, die im Original nicht enthalten waren – jetzt aber gespeichert werden müssen.
An der Compression-View erkennt ihr, ob ein Bild schon einmal zum JPG konvertiert wurde. Sieht das Ergebnis „blockartig“ aus, versucht ihr besser, an die Original-Daten des Bildes zu kommen.
Das Ergebnis sollte eher folgendermaßen aussehen und um einiges kleiner sein:
2. Sauberes Klonen von Objekten
Wollt ihr eine Grafik aus geklonten Objekten perfekt als PNG speichern, müssen diese absolut identisch sein, damit nur das erste Objekt Speicherplatz belegt. Achtet darauf, nicht versehentlich etwas um einen halben Pixel zu verschieben oder auf andere Weise zu verändern. Auch hier könnt ihr das Ergebnis mithilfe der Compression-View überprüfen.
3. Acht-Bit-Farbtiefe verwenden
Im Normalfall sollte die Qualität eines Acht-Bit-PNGs (maximal 256 Farben) immer ausreichend sein. Fehlende Töne werden per Dithering, also mithilfe von Punktmustern, simuliert. So entsteht der Eindruck zusätzlicher Farben und Graustufen.
„Flächige“ Bilder wie Logos benötigen fast nie 256 Farben. Eine gute Faustregel: Rechnet pro Farbe im Bild acht weitere hinzu, damit die Kantenglättung sauber aussieht. Besteht ein Logo aus Rot, Blau und Schwarz, sollte es reichen, den Farbregler auf 24 zu stellen.
4. Dirty Transparency
Als Dirty Transparency werden Bildbereiche bezeichnet, die zwar zu 100 Prozent transparent sind, aber in den Farbkanälen Rot, Grün und Blau noch sämtliche Farbinformationen beinhalten. Das passiert häufig bei maskierten Bildern und verschwendet Speicherplatz durch nicht sichtbare Bildinformationen.
Der Bereich um Lena wirkt transparent, in der Compression-View seht ihr aber deutlich, dass dort Daten komprimiert wurden:
Das gesäuberte Bild ist elf Prozent kleiner – bei gleichem Bildeindruck:
5. Posterization
Posterization reduziert die Farben innerhalb eines Bildes. RGB-Bilder haben oft mehr Farben, als das menschliche Auge unterscheiden kann. Durch die Posterization werden sehr ähnliche Töne zusammengefasst, was in den seltensten Fällen als störend wahrgenommen wird.
Durch mehr gleichartige Farbwerte arbeiten die PNG-Filter effizienter – und die Datei wird kleiner.
Spannend. Wie kommt man an die Compression View?
Christoph Erdmann, vielen Dank für diesen aufschlussreichen Beitrag!
Wie mein Vorkommentator auch von mir die Frage: Wie bekommt man die Compression View zu Gesicht?
Kannst du einen Online Compressor empfehlen wie z. B. tinypng.com, für schnelles, verlustfreies komprimieren?
Liebe Grüße,
Dennis
Hallo Corvin,
hallo Dennis,
auf Christoph Erdmann Seite ( https://compress-or-die.com/ )
findet ihr in sein „PNG Tool“ (rechts oben im Menü auf PNG klicken).
Nach Hochladen eines Bildes wird der Compression View des Bildes angezeigt.
Falls jemand weitere Tools zur Ansicht des Compression View kennt (vllt. sogar offline) wäre das auch für mich sehr interessant.
Viele Grüße
Tim
Hallo Dennis,
für eine kleine Dateigröße kann ich dir eigentlich jedes Tool empfehlen, in dem du Einstellungen machen kannst. Kannst du keine machen, können die Ergebnisse nur „OK“ sein. Dafür hast du weniger Arbeit, wie z.B. bei tinyPNG. Da der Qualitätsverlust beim Übergang zu PNG-8 subjektiv sehr unterschiedlich wahrgenommen werden kann, gibt es halt keine „perfekte“ Einstellung.
Viele Grüße,
Christoph