2010-11-27 4 views
6

wie kann ich md5 des pil objekts ohne speichern in der datei?md5 von pil objekt

imq.save('out.png') 
    hash = hashlib.md5(open('out.png','rb').read()).hexdigest() 

Antwort

4

könnten Sie schreiben Sie es auf einen StringIO statt, und nehmen Sie dann den Hash davon.

1

Sie können die folgende Klassenmethode PIL Image verwenden, um die Rohbilddaten an md5() zu senden.

im.getdata() => Sequenz

Gibt den Inhalt eines Bildes als Objektsequenz Pixelwerte enthält. Das Sequenzobjekt ist abgeflacht, so dass Werte für die erste Zeile direkt nach den Werten von Zeile Null usw. folgen.

Beachten Sie, dass die resultierende MD5-Hash der Verwendung dieser wird nicht die gleiche sein wie Ihr Beispielcode, weil es (zumindest teilweise) unabhängig von der jeweiligen Bilddateiformat verwendet wird, um das Bild zu speichern. Es könnte nützlich sein, wenn Sie tatsächliche Bilder unabhängig von dem bestimmten Bilddateiformat vergleichen möchten, in dem sie gespeichert werden können.

Um es zu verwenden, müssten Sie den MD5-Hash der Bilddaten irgendwo unabhängig von jeder Bilddatei wo speichern es könnte bei Bedarf abgerufen werden - im Gegensatz zur Generierung durch Lesen der gesamten Datei in den Speicher als binäre Daten wie der Code in Ihrer Frage. Stattdessen müssten Sie das Bild immer in PIL laden und dann die Methode getdata() verwenden, um Hashes zu berechnen.

5

Drehen @ Ignacio Antwort in Code, this answer mit helfen:

import StringIO, hashlib 

output = StringIO.StringIO() 
img.save(output) 
hash = hashlib.md5(output.getvalue()).hexdigest() 

Wie den anderen genannten Antwort Notizen, könnte dies zu einer KeyError führen, wenn PIL das Ausgabeformat automatisch zu erkennen versucht. Zur Vermeidung dieses Problems können Sie das Format manuell an:

img.save(output, format='GIF') 

(Anmerkung:. Ich verwendet habe, „img“ als Variable, anstatt Ihre „imq“, die ich angenommen war ein Tippfehler)

+0

Wenn ich versuche, entweder zu einem 'StringIO' oder' BytesIO' Objekt zu speichern, bekomme ich einen 'KeyError', weil das Format nicht abgeleitet werden kann; Die Bereitstellung eines bekannten Formats führt zu unterschiedlichen Fehlern. – FluxIX

+0

@FluxIX vermeide den KeyError mit kwargs format = 'foo' (wie du wahrscheinlich hast). Du müsstest die "verschiedenen Fehler" beschreiben, damit jemand dabei helfen kann. –

+0

Ich bat nicht um Hilfe bei den verschiedenen Fehlern, sondern spezifizierte den Parameter als ein Schlüsselwort. – FluxIX

12

Tatsächlich gibt es eine einfachere Lösung:

+5

Sieht so aus, als ob .tostring() ab 2.0 zugunsten von .tobytes() veraltet ist. – BrianTheLion

+1

In 2017 wird .tostring() nicht mehr unterstützt, stattdessen .tobytes() – ksopyla