Kompression eines PNG Bildes

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
splu
User
Beiträge: 15
Registriert: Freitag 30. Juni 2006, 11:26

Hallo zusammen,

ich öffne aktuell ein PNG und würde es nach der Verarbeitung gerne komprimiert speichern.

Code: Alles auswählen

im.save(result,'PNG')
Speichert das Bild mit der Standardeinstellung. Doch wie kann ich dies beeinflussen?

Hierzu muss der 'optimale' Encoder angegeben werden? Bzw der Parameter 'optimize'? Wie kann ich diesen verwenden?

Selbst wenn ich das Bild nur öffne und direkt wieder Speichere ist es 2x so groß wie zuvor

Code: Alles auswählen

im = Image.open(source)
im.save(result,'PNG')
Gruß splu
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Ich vermute, dass deine Ausgangsgrafik eine reduzierte Farbpalette hat. So kann man die Farben z.B. von ~16 Mio. auf ~65 Tausend oder 256 oder 16 runterschrauben. Wenn ich mich nicht irre reduzieren eine Grafikprogramme die Palette auch noch weiter, eben je nachdem wieviele Farben wirklich benötigt werden.

Sofern nun PIL die Palette beim Laden wieder vergrößert, ist das Resultat beim Speichern entsprechend größer. Die Paletten vorher und nachher würde ich mal vergleichen und/oder in der Doku nach Anhaltspunkten in diese Richtung suchen. Lossy-Komprimierung wie bei JPEG gibt es bei PNGs ja nicht.
BlackJack

Na einfach ``im.save('name.png', optimize=True)``.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

schau doch mal in die Docu von PIL... ich wette die hilft dir da weiter :idea:
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
splu
User
Beiträge: 15
Registriert: Freitag 30. Juni 2006, 11:26

In der PIL Library war ich bereits zu Gange, da ich daraus bisher keine Lösung gefunden habe bin ich ja hier gelandet :)

Durch den Parameter optimize=True erziele ich leider das gleiche ergebnis. Das gespeicherte Bild ist ~2x so groß wie das Ursprungsbild.

Was ich gerade sehe, bei dem Ursprungsbild wird eine Bittiefe von 32 angezeigt. Das neue Bild besitzt eine Bittiefe von 24.
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Aber das Ursprungsbild ist auch'ne PNG, oder?... Tut mir leid für die dumme Frage, aber ich hab schon Pferde kotzen sehen!
BlackJack

@splu: Um was für ein Bild handelt es sich denn? Und wie wurde das gespeichert/erzeugt?

Es gibt bei PNG die Möglichkeit verschiedene, reversible Filter auf die Zeilen an zu wenden, bevor die Daten komprimiert werden. Zusammen mit den Stellschrauben, die der Kompressionsalgorithmus bietet, gibt es da sehr viele Kombinationen die man durchprobieren müsste, um wirklich die optimale Kompression heraus zu finden. Die Programme verwenden deshalb in der Regel Heuristiken oder recht einfache Ansätze um möglichst kleine PNGs zu erzeugen. Darum bekommt man mit unterschiedlichen Programmen auch unterschiedliche Dateigrössen.

Wenn da wirklich der Alphakanal entfernt wurde, dann war der wahrscheinlich komplett opak und damit überflüssig.
splu
User
Beiträge: 15
Registriert: Freitag 30. Juni 2006, 11:26

Die Ursprungsbilder sind ebenfalls PNG's jedoch werden sie von einem GIS-Server geschrieben. Als Konfigurationseinstellung wurde dort "nur" vorgenommen, dass es sich um PNG24 Handelt und das Bild keine Kompression besitzen soll.

@BlackJack:

Wie kann ich eine Mögliche Kompression denn beim Speichern angeben? Genau da kam ich nicht weiter. Beim einfachen Image object gibt es zwar den zusätzlichen Parameter "options" jedoch habe ich keine weiteren Informationen gefunden wie man dort möglicherweise auch ein Kompressionsverfahren angeben kann.
BlackJack

Wieso haben die ursprünglichen Bilder denn eine Bittiefe von 32 wenn PNG24 gewählt wurde? Kannst Du so ein Bild mal irgendwo hochladen, damit man sich dass mal anschauen kann?

PIL bietet ausser dem `optimize` keine Einflussmöglichkeiten für das Speichern von PNG bei RGB-Bildern.
splu
User
Beiträge: 15
Registriert: Freitag 30. Juni 2006, 11:26

Ein Beispielbild ist:

** link entfernt **
Zuletzt geändert von splu am Freitag 29. Februar 2008, 16:24, insgesamt 1-mal geändert.
BlackJack

Das ist ein interessantes Problem. Es liegt nicht an den Filtern. Die sehen bei beiden ziemlich gleich aus. Aus irgend welchen Gründen erzeugt die `zlib`-Kompression bei PIL für die gleichen Daten mehr Bytes.

Die beiden Hauptunterschiede sind, dass das Original die Daten nur mit der Kompressionsstärke "normal" und PIL mit "maximum" arbeitet, und das Original auf mehrere "Chunks" verteilt ist, während PIL einen erzeugt. Aber wenn man das Original mit ``convert`` von ImageMagick "konvertiert", dann hat man auch die Einstellung "maximum" und nur einen Chunk, aber die Datei ist kleiner ─ etwas grösser als das Original.

Letztendlich: Ist das so schlimm? Doppelt so grosse Dateien hört sich zwar viel an, andererseits komprimiert PIL in dem Beispielbild nur 0.7% schlechter, was IMHO eine recht geringe Abweichung ist. Die Ursprungsdaten sind immerhin 3 MiB gross.
splu
User
Beiträge: 15
Registriert: Freitag 30. Juni 2006, 11:26

Mit Ziel des Prozesses soll auch die besser kompression der Datei sein. Sie soll also weniger Speicherplatz in Anspruch nehmen. Es handelt es sich ja nicht um 10 solche Bilder sondern mehrer 10-tausende :)

Danke für eure Hinweise und Hilfe bisher. Vielleicht muss ich dann doch weg von Python für dieses Problem :P
BlackJack

Dann solltest Du wirklich besser Programme benutzen, die auf so etwas spezialisiert sind.

Kleiner Test mit `optipng` hat nach 10 Sekunden Rechenzeit das Original um 44% verkleinert auf 13198 Bytes gebracht.
Antworten