2010-12-04 17 views
13

Ich spiele gerade mit PIL-Bibliothek in Python und ich frage mich, wie ich die Qualität der gegebenen JPG-Bild bestimmen. Ich versuche JPG-Bild zu öffnen, tue etwas dazu und speichere es in seiner ursprünglichen Qualität erneut. Image.save lassen Sie mich die gewünschte Qualität zu bestimmen:Ermitteln der JPG-Qualität in Python (PIL)

im.save(name, quality = x) 

, aber ich sehe keine Möglichkeit, Original zu extrahieren. Für jetzt bin ich nur raten und versuche, eine Ausgabedatei der gleichen Größe wie die Eingabe durch binäre Suche auf 'Qualität' Parameter zu haben, aber das ist keine akzeptable langfristige Lösung :)
Ich habe auch versucht mit: Image.info aber am meisten meiner Bilder haben dort keine nützlichen Informationen (zB: 'adobe', 'icc_profile', 'exif', 'adobe_transform')
Hilfe!

+1

Relevante Informationen: http://superuser.com/questions/62730/how-to-find-the-jpg-quality/91083#91083 – unutbu

+0

Im Allgemeinen ist es nicht möglich, die präzise zu erholen Qualitätswert, der verwendet wird, um eine JPEG-Datei zu komprimieren, da es verschiedene Möglichkeiten gibt, die gespeicherten Informationen zu reduzieren. Der Qualitätswert ist nur eine Richtlinie für den Encoder, aber, wie @unutbu hervorhebt, kann einige Software heldenhaft raten. – andrewmu

+1

Es ist wahrscheinlich erwähnenswert, dass JPEG ein verlustbehaftetes Format ist, so dass das Öffnen und Speichern eines Bildes die Bildqualität verschlechtert, auch wenn die Option "Qualität" auf denselben Wert eingestellt ist. –

Antwort

22

In PIL (und meistens in allen Software/Libraries, die libjpeg verwenden) wird die Qualitätseinstellung verwendet, um die Quantisierungstabelle zu erstellen (ref.). In libjpeg skaliert die Qualitätszahl die Werte der Beispieltabelle (aus der JPEG-Spezifikation Abschnitt K.1). In anderen Libraries gibt es verschiedene Tabellen, die verschiedenen Qualitäten zugeordnet sind (zB Photoshop, Digitalkamera).

Also, in anderen Worten, die Qualität entspricht der Quantisierungstabelle, also ist es komplexer als nur eine Zahl.

Wenn Sie Ihre geänderten Bilder mit der gleichen "Qualität" speichern möchten, müssen Sie nur die gleiche Quantisierungstabelle verwenden. Glücklicherweise ist die Quantisierungstabelle in jedem JPEG eingebettet. Leider ist es beim Speichern in PIL nicht möglich, eine Quantisierungstabelle anzugeben. cjpeg, eine Befehlszeile Dienstprogramme, die mit libjpeg kommen, können das tun.

Hier einige grobe Code, der ein jpeg mit einer bestimmten Quantisierungstabelle speichern:

from subprocess import Popen, PIPE 
from PIL import Image, ImageFilter 

proc = Popen('%s -sample 1x1 -optimize -progressive -qtables %s -outfile %s' % ('path/to/cjpeg', '/path/ta/qtable', 'out.jpg'), shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE) 
P = '6' 
if im.mode == 'L': 
    P = '5' 
stdout, stderr = proc.communicate('P%s\n%s %s\n255\n%s' % (P, im.size[0], im.size[1], im.tostring())) 

Sie müssen den Weg finden, die Quantisierungstabelle aus dem ursprünglichen jpeg zu extrahieren.djpeg kann tun, dass (Teil libjpeg):

djpeg -verbose -verbose image.jpg > /dev/null 

Sie auch die Probenahme zu finden und stellen Sie benötigen. Weitere Informationen hierzu finden Sie unter here. Sie können an test_subsampling

UPDATE schauen auch

ich eine PIL Gabel hat die Möglichkeit, hinzuzufügen Subsampling oder Quantisierungstabellen oder beide angeben, wenn JPEG speichern. Sie können auch quality='keep' beim Speichern angeben, und das Bild wird mit denselben Quantisierungstabellen und Subsampling wie das Original gespeichert (Original muss ein JPEG sein). Es gibt auch einige Voreinstellungen (basierend auf Photoshop), die Sie beim Speichern an die Qualität übergeben können. My fork.

UPDATE 2

ist mein Code jetzt Teil von Pillow 2.0. So tun gerade:

pip install Pillow 
+2

Die Quantisierungstabellen sind auch im Attribut 'quantisation' eines' PIL.JpegImagePlugin.JpegImageFile' verfügbar (das ist der Typ, den Sie erhalten, wenn Sie eine JPEG-Datei "Image.open" öffnen). – adw

+0

Das ist gut zu wissen. Das einzige, was in PIL fehlt, ist eine Möglichkeit, die Quantisierungstabelle beim Speichern anzugeben (zu übergeben). – Etienne

+0

Süß, vor allem, dass es mit 3,3 funktioniert; Ich bin froh, dass du dich an diese alte Frage erinnerst :) –

-3

Soweit ich Sie verstanden habe, ist dies nicht möglich. Das JPEG-Format wird komprimiert, indem 75% der Farbdaten entfernt werden oder indem Farben vereinfacht werden. Es gibt keine Möglichkeit, die Farbqualität zu verbessern.

+0

JPEG komprimiert nicht durch Entfernen von 75% der Farbdaten oder durch Vereinfachung der Farben. Es wird eine Farbraumkonvertierung in einen effizienteren Farbraum (YCbCr) durchgeführt, aber das ist nur der erste Schritt. – kidjan

+0

Zu Ihrer Information: JPEG komprimiert normalerweise, indem 75% der Farbdaten entfernt werden (4: 2: 0 Subsampling). – Arel

4

Qualität wird verwendet, um die im JPEG gespeicherten Daten zu generieren. Diese Nummer ist nicht im JPEG gespeichert.

Eine Möglichkeit, die Qualität zu bestimmen, besteht darin, die leere 8x8-Pixelzelle des Bildes vor der Bearbeitung zu übernehmen und die JPEG-Komprimierungsformel genau so auszuführen, dass sie dem Original nahekommt. Sie müssen aus dem Ergebnis eine Distanzfunktion zu Ihrem Original entwickeln (Pixeldifferenz).

Sie werden immer noch eine binäre Suche mit Qualität, aber es ist eine viel kleinere Menge an Arbeit.

ist hier Informationen darüber, wie die JPEG-Komprimierung arbeitet

http://www.dspguide.com/ch27/6.htm

Hier ist eine andere Art und Weise von einer MS FAQ

http://support.microsoft.com/kb/324790

Sie haben von C# zu übersetzen.