Wie ist PNG verlustfrei, wenn es einen Komprimierungsparameter hat?

156

PNG-Dateien sollen verlustfrei komprimiert werden. Wenn ich mich jedoch in einem Bildeditor wie GIMP befinde und versuche, ein Bild als PNG-Datei zu speichern, wird nach dem Komprimierungsparameter gefragt, der zwischen 0 und 9 liegt das komprimierte Bild, wie macht es PNG verlustfrei?

Erhalte ich nur dann ein verlustfreies Verhalten, wenn ich den Komprimierungsparameter auf 9 setze?

pkout
quelle
40
Die meisten verlustfreien Komprimierungsalgorithmen verfügen über einstellbare Werte (z. B. die Größe des Wörterbuchs), die in einem Schieberegler "Wie viel Aufwand bei der Minimierung der Ausgabegröße erforderlich ist" verallgemeinert werden. Dies gilt für ZIP, GZip, BZip2, LZMA, ...
Daniel B
20
Die Frage könnte anders gestellt werden. Wenn durch die Komprimierung keine Qualität verloren geht, warum nicht immer die Komprimierung mit der kleinsten Größe verwenden? Die Antwort wäre dann, weil es mehr RAM und mehr CPU-Zeit zum Komprimieren und Dekomprimieren benötigt. Manchmal möchten Sie eine schnellere Komprimierung und kümmern sich nicht so sehr um das Komprimierungsverhältnis.
Kasperd
14
Die PNG-Komprimierung ist nahezu identisch mit ZIPping-Dateien. Sie können sie mehr oder weniger komprimieren, aber Sie erhalten die genaue Datei zurück, wenn sie dekomprimiert wird - das macht sie verlustfrei.
Mikebabcock
13
Bei den meisten Komprimierungsprogrammen wie Zip und Rar können Sie die Komprimierungsstufe eingeben, mit der Sie zwischen einer kürzeren <-> Dateizeit wählen können. Dies bedeutet nicht, dass diese Software Daten während der Komprimierung verwirft. Diese Einstellung (in GIMP, pngcrush usw.) ist ähnlich.
Salman A
2
@naxa: Es gibt keine Einschränkungen, wie verlustfrei png wirklich ist. Es ist immer 100% verlustfrei. Der Artikel warnt Sie nur vor Fehlern, die einige alte Browser in ihrer PNG-Implementierung hatten, um mit der Gammakorrektur umzugehen. Und das ist nur dann sinnvoll, wenn Sie die Farbe mit CSS-Farben abgleichen müssen (die nicht gammakorrigiert sind).
Pauli L

Antworten:

183

PNG ist verlustfrei. GIMP verwendet in diesem Fall höchstwahrscheinlich einfach nicht das beste Wort. Stellen Sie es sich als "Qualität der Komprimierung" oder mit anderen Worten "Grad der Komprimierung" vor. Bei geringerer Komprimierung erhalten Sie eine größere Datei, die Produktion dauert jedoch kürzer, während bei höherer Komprimierung die Produktion einer kleineren Datei länger dauert. In der Regel erzielen Sie eine geringere Rendite (dh eine geringere Größenverringerung im Vergleich zu der Zeit, die Sie benötigen), wenn Sie die höchsten Komprimierungsstufen erreichen, aber es liegt an Ihnen.

jjlin
quelle
42
Außerdem verfügt die PNG-Komprimierung tatsächlich über viele einstellbare Parameter, bei denen Anpassungen in beide Richtungen die Ausgabegröße in Abhängigkeit vom Inhalt der Quelle verringern können. Dies ist weitaus komplexer als ein einfacher "besserer" und "schlechterer" Schieberegler. Für allgemeine Zwecke ist es nicht allzu wichtig, aber wenn Sie das absolut Kleinste wollen pngcrush, können Sie mit einem solchen Werkzeug viele Variationen auf das kleinstmögliche vergleichen.
Bob
4
Ein höherer Komprimierungsgrad verlängert die Komprimierungszeit, wirkt sich dies jedoch auch auf die Dekomprimierung aus ?
Nolonar
10
@Nolonar Im Allgemeinen nein; Wenn eine höhere Komprimierungsstufe vorliegt, verringert sich normalerweise die Dekomprimierungszeit, da weniger Daten gelesen und verarbeitet werden müssen. Die längere Komprimierungszeit ergibt sich aus einer gründlicheren Suche nach zu komprimierenden Mustern (zu vereinfachend).
flauschiger
1
Bei der Antwort von @fluffy LordNeckbeard dauerte die höchste Komprimierung fünfmal länger als die niedrigste.
André Chalella
1
Bei PNG ist eine längere Dekomprimierungszeit für besser komprimierte Dateien durchaus üblich. Das Problem ist, dass mit PNG ein möglicher Trick darin besteht, den Komprimierungsalgorithmus immer wieder anzuwenden, solange die Datei kleiner wird. Sobald die Größe zunimmt, hören Sie auf, sie anzuwenden. Es ist also gut möglich, dass Sie den Komprimierungsalgorithmus fünf- oder sechsmal anwenden, was bedeutet, dass Sie die Datei fünf- oder sechsmal dekomprimieren müssen, um das Bild anzuzeigen.
Du
213

PNG ist komprimiert, aber verlustfrei

Die Komprimierungsstufe ist ein Kompromiss zwischen Dateigröße und Kodierungs- / Dekodierungsgeschwindigkeit. Um dies zu verallgemeinern, haben auch Nicht-Bildformate wie FLAC ähnliche Konzepte.

Unterschiedliche Komprimierungsstufen, gleiche dekodierte Ausgabe

Obwohl die Dateigrößen aufgrund der unterschiedlichen Komprimierungsstufen unterschiedlich sind, ist die tatsächlich decodierte Ausgabe identisch.

Sie können die MD5- Hashes der decodierten Ausgaben mit ffmpegdem MD5-Muxer vergleichen .

Dies zeigt sich am besten an einigen Beispielen:

Erstellen Sie PNG-Dateien:

$ ffmpeg -i input -vframes 1 -compression_level 0 0.png
$ ffmpeg -i input -vframes 1 -compression_level 100 100.png
  • Standardmäßig ffmpegwird -compression_level 100für die PNG-Ausgabe verwendet.

Dateigröße vergleichen:

$ du -h *.png
  228K    0.png
  4.0K    100.png

Dekodiere die PNG-Dateien und zeige MD5-Hashes:

$ ffmpeg -loglevel error -i 0.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83

$ ffmpeg -loglevel error -i 100.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83

Da beide Hashes identisch sind, können Sie sicher sein, dass die dekodierten Ausgaben (das unkomprimierte, unformatierte Video) exakt gleich sind.

Logan
quelle
26
+1 wusste nicht, dass ffmpeg mit pngs umgehen kann.
Lekensteyn
21
@Lekensteyn Es ist großartig, um Screenshots zu machen . Beispiel zum Überspringen von 30 Sekunden und Aufnehmen eines Screenshots: ffmpeg -ss 30 -i input -vframes 1 output.pngAuch zum Erstellen von Videos aus Bildern und umgekehrt geeignet.
Logan
Bedeutet das, dass das PNG jedes Mal dekomprimiert werden muss, wenn es gerendert werden muss? Denn wenn das stimmt, müssen wir
akshay2000 28.11.14
Wenn Sie die Datei erneut von der Festplatte oder vom Cache lesen, muss sie dekomprimiert werden. Innerhalb derselben Seite kann der Cache die dekomprimierte Version jedoch wahrscheinlich wiederverwenden.
David Mårtensson
1
@ akshay2000 Hängt davon ab, wie das Programm funktioniert, das das PNG rendert. Normalerweise wird die Datei von der Festplatte gelesen, dekomprimiert und im RAM gepuffert. Solange es im RAM gepuffert ist, muss es nicht erneut dekomprimiert werden.
xZise
24

Die PNG-Komprimierung erfolgt in zwei Schritten.

  1. Durch die Vorkomprimierung werden die Bilddaten so neu angeordnet, dass sie durch einen Mehrzweck-Komprimierungsalgorithmus besser komprimiert werden können.
  2. Die eigentliche Komprimierung wird von DEFLATE durchgeführt, das nach doppelten Byte-Sequenzen sucht und diese durch kurze Token ersetzt.

Da Schritt 2 eine sehr zeit- / ressourcenintensive Aufgabe ist, verwendet die zugrunde liegende zlib-Bibliothek (Kapselung von RAW-DEFLATE) einen Komprimierungsparameter von 1 = Schnellste Komprimierung, 9 = Beste Komprimierung, 0 = Keine Komprimierung. Daher kommt der Bereich 0-9, und GIMP übergibt diesen Parameter einfach an zlib. Beachten Sie, dass Ihr PNG auf Stufe 0 tatsächlich etwas größer ist als die entsprechende Bitmap.

Level 9 ist jedoch nur das "Beste", was zlib versuchen wird, und ist immer noch eine Kompromisslösung .
Um wirklich ein Gefühl dafür zu bekommen, wenn Sie bereit sind, 1000-mal mehr Rechenleistung für eine umfassende Suche aufzuwenden, können Sie mit zopfli anstelle von zlib eine um 3-8% höhere Datendichte erzielen .
Die Komprimierung ist immer noch verlustfrei, es ist nur eine optimalere DEFLATE-Darstellung der Daten. Dies nähert sich den Grenzen einer zlib-kompatiblen Bibliothek und ist daher die beste Komprimierung, die mit PNG erzielt werden kann.

Adria
quelle
2
Hinweis: Die Dekomprimierungszeit ist unabhängig von der Komprimierungsstufe oder der Anzahl der Iterationen bei Verwendung von zopflipng gleich.
Adria
16

Eine Hauptmotivation für das PNG-Format war die Schaffung eines Ersatzes für GIF, der nicht nur kostenlos war, sondern auch in praktisch jeder Hinsicht eine Verbesserung darstellte. Dadurch ist die PNG-Komprimierung völlig verlustfrei - das heißt, die ursprünglichen Bilddaten können Bit für Bit genau rekonstruiert werden - genau wie in GIF und den meisten TIFF-Formen.

PNG verwendet ein zweistufiges Komprimierungsverfahren:

  1. Vorkomprimierung: Filterung (Vorhersage)
  2. Komprimierung: DEFLATE (siehe Wikipedia )

Der Vorkomprimierungsschritt wird als Filtern bezeichnet. Hierbei handelt es sich um eine Methode zur reversiblen Transformation der Bilddaten, damit die Hauptkomprimierungsmaschine effizienter arbeiten kann.

Betrachten Sie als einfaches Beispiel eine Folge von Bytes, die gleichmäßig von 1 auf 255 ansteigt:

1, 2, 3, 4, 5, .... 255

Da die Sequenz keine Wiederholung enthält, wird sie entweder sehr schlecht oder gar nicht komprimiert. Eine triviale Modifikation der Sequenz - nämlich das erste Byte in Ruhe zu lassen, aber jedes nachfolgende Byte durch den Unterschied zwischen ihm und seinem Vorgänger zu ersetzen - transformiert die Sequenz in eine extrem komprimierbare Menge:

1, 1, 1, 1, 1, .... 1

Die obige Transformation ist verlustfrei, da keine Bytes ausgelassen wurden, und ist vollständig umkehrbar. Die komprimierte Größe dieser Serie wird stark reduziert, aber die ursprüngliche Serie kann immer noch perfekt wiederhergestellt werden.

Tatsächliche Bilddaten sind selten so perfekt, aber das Filtern verbessert die Komprimierung von Graustufen- und Echtfarbenbildern und kann auch bei einigen Palettenbildern hilfreich sein. PNG unterstützt fünf Filtertypen, und ein Encoder kann für jede Pixelzeile im Bild einen anderen Filter verwenden:

Bild

Der Algorithmus arbeitet mit Bytes, aber für große Pixel (z. B. 24-Bit-RGB oder 64-Bit-RGBA) werden nur entsprechende Bytes verglichen, was bedeutet, dass die roten Komponenten der Pixelfarben getrennt von den grünen und blauen Pixelkomponenten behandelt werden.

Um den besten Filter für jede Zeile auszuwählen, müsste ein Encoder alle möglichen Kombinationen testen. Dies ist eindeutig unmöglich, da selbst ein Bild mit 20 Zeilen das Testen von mehr als 95 Billionen Kombinationen erfordern würde, wobei das "Testen" das Filtern und Komprimieren des gesamten Bildes umfassen würde.

Komprimierungsstufen werden normalerweise als Zahlen zwischen 0 (keine) und 9 (beste) definiert. Diese beziehen sich auf Kompromisse zwischen Geschwindigkeit und Größe und darauf, wie viele Kombinationen von Zeilenfiltern ausprobiert werden sollen. Bezüglich dieser Komprimierungsstufen gibt es keine Standards. Daher verfügt jeder Bildeditor möglicherweise über eigene Algorithmen, um zu bestimmen, wie viele Filter bei der Optimierung der Bildgröße verwendet werden sollen.

Komprimierungsstufe 0 bedeutet, dass überhaupt keine Filter verwendet werden, was zwar schnell, aber verschwenderisch ist. Höhere Werte bedeuten, dass immer mehr Kombinationen für Bildzeilen ausprobiert werden und nur die besten beibehalten werden.

Ich würde vermuten, dass der einfachste Ansatz für die beste Komprimierung darin besteht, jede Zeile mit jedem Filter inkrementell zu komprimieren, das kleinste Ergebnis zu speichern und für die nächste Zeile zu wiederholen. Dies bedeutet, dass das gesamte Bild fünfmal gefiltert und komprimiert wird. Dies kann ein angemessener Kompromiss für ein Bild sein, das viele Male übertragen und decodiert wird. Niedrigere Komprimierungswerte können nach Ermessen des Werkzeugentwicklers weniger bewirken.

Zusätzlich zu Filtern kann die Komprimierungsstufe auch die zlib-Komprimierungsstufe beeinflussen, die eine Zahl zwischen 0 (keine Deflate) und 9 (maximale Deflate) ist. Wie sich die angegebenen 0-9-Stufen auf die Verwendung von Filtern auswirken, die die Hauptoptimierungsfunktion von PNG darstellen, hängt weiterhin vom Entwickler des Tools ab.

Die Schlussfolgerung ist, dass PNG über einen Komprimierungsparameter verfügt, der die Dateigröße erheblich reduzieren kann, ohne dass auch nur ein Pixel verloren geht.

Quellen:

Wikipedia Portable Network Graphics
libpng-Dokumentation Kapitel 9 - Komprimierung und Filterung

Harrymc
quelle
1
Ich glaube nicht, dass die Einstellung der Komprimierungsstufe die Verwendung von Filtern ändert. Die Stufe 1-9-Einstellung wählt wahrscheinlich nur die zlib-Komprimierungsstufe 1-9 aus, und Stufe 0 bedeutet, dass der Deflate-Algorithmus überhaupt nicht verwendet wird. Die meisten Implementierungen ändern wahrscheinlich nicht die Filter pro Zeile, sondern verwenden immer nur den Pfadfilter.
Pauli L
@PauliL: Dem stimme ich nicht zu, da es bei allen Vergleichen der PNG-Komprimierungssoftware sehr große Unterschiede zwischen den Größen der generierten Bilder gibt. Wenn für alle Produkte dieselben Parameter für dieselbe Bibliothek verwendet wurden, sollten alle Größen und die Geschwindigkeit gleich sein.
Harrymc
Haben Sie Links zu solchen Vergleichen?
Pauli L
@ PauliL: Eine schnelle Suche ergab diesen Vergleich .
Harrymc
@PauliL: Sie haben wahrscheinlich Recht, dass die zlib-Komprimierungsstufen von den Komprimierungsstufen von PNG beeinflusst werden. Ich habe meine Antwort entsprechend geändert, obwohl kein Komprimierungswerkzeug dokumentiert, was sie genau tun. Vielleicht liegt die Erklärung für die Tools mit den schlechtesten Ergebnissen darin, dass sie überhaupt keine Filter verwenden, sondern nur die Zlib-Komprimierung.
Harrymc
5

OK, ich bin zu spät für das Kopfgeld, aber hier ist trotzdem meine Antwort.

PNG ist immer verlustfrei . Es verwendet einen Deflate / Inflate-Algorithmus, ähnlich wie er in Zip-Programmen verwendet wird.

Der Deflate-Algorithmus durchsucht wiederholte Sequenzen von Bytes und ersetzt diese durch Tags. Die Einstellung für die Komprimierungsstufe gibt an, wie viel Aufwand das Programm benötigt, um die optimale Kombination von Byte-Sequenzen zu finden, und wie viel Speicher dafür reserviert ist. Es ist ein Kompromiss zwischen Zeit und Speichernutzung im Vergleich zur komprimierten Dateigröße. Moderne Computer sind jedoch so schnell und verfügen über genügend Speicher, dass nur die höchste Komprimierungseinstellung verwendet werden muss.

Viele PNG-Implementierungen verwenden die zlib-Bibliothek zur Komprimierung. Zlib hat neun Komprimierungsstufen, 1-9. Ich kenne die Interna von Gimp nicht, aber da es die Komprimierungsstufen 0-9 (0 = keine Komprimierung) hat, würde ich davon ausgehen, dass diese Einstellung einfach die Komprimierungsstufe von zlib auswählt.

Der Deflate-Algorithmus ist ein allgemeiner Komprimierungsalgorithmus , der nicht zum Komprimieren von Bildern entwickelt wurde. Im Gegensatz zu den meisten anderen verlustfreien Bilddateiformaten ist das PNG-Format nicht darauf beschränkt. Die PNG-Komprimierung nutzt das Wissen, dass ein 2D-Bild komprimiert wird . Dies wird durch sogenannte Filter erreicht .

(Filter ist hier eigentlich ein etwas irreführender Begriff. Es ändert den Bildinhalt nicht wirklich, sondern codiert ihn nur anders. Genauere Bezeichnung wäre Delta-Encoder.)

Die PNG-Spezifikation spezifiziert 5 verschiedene Filter (einschließlich 0 = keine). Der Filter ersetzt absolute Pixelwerte durch Abweichungen vom vorherigen Pixel nach links, nach oben, diagonal oder durch Kombinationen davon. Dies kann das Kompressionsverhältnis erheblich verbessern. Jede Scanlinie im Bild kann einen anderen Filter verwenden. Der Encoder kann die Komprimierung optimieren, indem er für jede Zeile den besten Filter auswählt.

Einzelheiten zum PNG-Dateiformat finden Sie unter PNG-Spezifikation .

Da es praktisch unendlich viele Kombinationen gibt, können nicht alle ausprobiert werden. Daher wurden verschiedene Arten von Strategien entwickelt, um eine wirksame Kombination zu finden. Die meisten Bildbearbeiter versuchen wahrscheinlich nicht einmal, die Filter zeilenweise zu optimieren, sondern verwenden lediglich feste Filter (höchstwahrscheinlich Paeth).

Ein Kommandozeilenprogramm pngcrush versucht verschiedene Strategien, um das beste Ergebnis zu erzielen . Die Größe von PNG-Dateien, die mit anderen Programmen erstellt wurden, kann erheblich reduziert werden. Bei größeren Bildern kann dies jedoch einige Zeit in Anspruch nehmen. Siehe Source Forge - pngcrush .

Pauli L
quelle
3

Komprimierungsgrad in verlustfreien Sachen ist immer nur der Handel mit codierten Ressourcen (normalerweise Zeit, manchmal auch RAM) im Vergleich zur Bitrate. Qualität ist immer 100%.

Natürlich können verlustfreie Kompressoren NIEMALS eine tatsächliche Kompression garantieren . Zufällige Daten sind inkompressibel, es gibt kein zu findendes Muster und keine Ähnlichkeit. Shannon Informationstheorie und all das. Der springende Punkt bei der verlustfreien Datenkomprimierung ist, dass Menschen normalerweise mit nicht zufälligen Daten arbeiten. Für die Übertragung und Speicherung können wir sie jedoch auf so wenige Bits wie möglich komprimieren. Hoffentlich so nah wie möglich an der Kolmogorov-Komplexität des Originals.

Egal, ob es sich um generische Zip- oder 7z-Daten, PNG-Bilder, Flac-Audio oder H.264-Video (im verlustfreien Modus) handelt, es ist dasselbe. Bei einigen Komprimierungsalgorithmen, wie z. B. lzma (7zip) und bzip2, erhöht das Hochdrehen der Komprimierungseinstellung die CPU-Zeit des DECODERS (bzip2) oder häufiger nur die benötigte RAM-Größe (lzma und bzip2 und h.264 mit mehr Referenzrahmen). . Häufig muss der Decoder mehr decodierte Ausgabe im RAM speichern, da das Decodieren des nächsten Bytes auf ein Byte verweisen kann, das vor vielen Megabytes decodiert wurde (z. B. würde ein Videoframe, das demjenigen vor einer halben Sekunde am ähnlichsten ist, mit Verweisen auf 12 Frames zurück codiert ). Dasselbe gilt für bzip2 und die Auswahl einer großen Blockgröße, aber das dekomprimiert auch langsamer. lzma hat ein Wörterbuch mit variabler Größe, und Sie könnten Dateien erstellen, für die 1 erforderlich wäre.

Peter Cordes
quelle
Hmmm, ich habe eine Implementierung gesehen, mit der Schrittmotor und Kopf direkt gesteuert werden können, um eine verlustfreie Komprimierung zu gewährleisten. Die Manchester-Codierung ist mit einer hochauflösenden Taktquelle leicht zu übertreffen.
Joshua
@ Joshua: Die Verwendung eines physischen Speicherformats mit höherer Dichte ist nicht dasselbe wie Datenkomprimierung ...
SamB
0

Erstens ist PNG immer verlustfrei. Das scheinbare Paradoxon beruht auf der Tatsache, dass zwei verschiedene Arten der Komprimierung möglich sind (für jede Art von Daten): verlustbehaftet und verlustfrei.

Die verlustfreie Komprimierung komprimiert die Daten (dh die Dateigröße) mithilfe verschiedener Tricks, wobei alles erhalten bleibt und keine Annäherung erfolgt. Infolgedessen ist es möglich, dass verlustfreie Komprimierung überhaupt nicht in der Lage ist, Dinge zu komprimieren. (Technisch gesehen können Daten mit hoher Entropie für verlustfreie Methoden nur sehr schwer oder gar nicht komprimierbar sein.) Eine verlustbehaftete Komprimierung nähert sich den tatsächlichen Daten an, die Approximation ist jedoch unvollständig.

Hier ist ein triviales Beispiel für verlustfreie Komprimierung: Wenn Sie ein Bild aus 1.000 schwarzen Pixeln haben, können Sie anstelle des 1000-fachen Speicherns des Schwarzwerts einen Zählwert (1000) und einen Schwarzwert speichern und so 1000 Pixel komprimieren. " Bild "in nur zwei Zahlen. (Dies ist eine rohe Form einer verlustfreien Komprimierungsmethode, die als Lauflängencodierung bezeichnet wird.)

GregD
quelle