2010-11-27 18 views
6

cómo puedo obtener md5 del objeto pil sin guardarlo en el archivo?md5 del objeto pil

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

Respuesta

4

Se puede escribir a un StringIO lugar, y luego tomar el hash de ello.

1

Puede utilizar el siguiente método de clase PIL Image para obtener los datos de imagen sin formato para alimentar a md5().

im.getdata() => secuencia

devuelve el contenido de una imagen como un objeto secuencia que contiene pixel valores. El objeto de secuencia es aplanado, por lo que los valores para la línea siguen directamente después de los valores de línea cero, y así sucesivamente.

Tenga en cuenta que el hash MD5 como resultado del uso de este no lo hará sea el mismo que el código de ejemplo, ya que es (al menos parcialmente) independiente del formato de archivo de imagen particular usado para guardar la imagen. Podría ser útil si quisiera comparar imágenes reales independientes del formato de archivo de imagen particular en el que se guardan.

Para usarlo, deberá almacenar el hash MD5 de los datos de imagen en algún lugar independiente de cualquier archivo de imagen donde podría recuperarse cuando sea necesario, en lugar de generarlo leyendo todo el archivo en la memoria como lo hacen los datos binarios, como el código en su pregunta. En su lugar, deberá cargar siempre la imagen en el PIL y luego utilizar el método getdata() para calcular hash.

5

Volviendo @ respuesta de Ignacio en código, usando this answer para ayudar:

import StringIO, hashlib 

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

Como las otras notas de respuesta de referencia, esto podría conducir a una KeyError si PIL intenta detectar automáticamente el formato de salida. Para evitar este problema, puede especificar el formato de forma manual:

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

(Nota:. He usado "img" como la variable, en lugar de su "imq" que asumí que era un error tipográfico)

+0

Cuando intento para salvar a cualquiera de un '' StringIO' o BytesIO' objeto consigo un 'KeyError' porque el formato no puede deducirse; proporcionar un formato conocido produce diferentes errores. – FluxIX

+0

@FluxIX evita el KeyError con el formato kwargs = 'foo' (como probablemente lo hiciste). Tendría que describir los "diferentes errores" para que cualquiera pueda ayudar con eso. –

+0

No estaba pidiendo ayuda con los diferentes errores, simplemente especificando el parámetro como un argumento clave. – FluxIX

12

en realidad no es la solución más simple:

hashlib.md5(img.tostring()).hexdigest() 
+5

Parece que .tostring() está en desuso a partir de 2.0 a favor de .tobytes() – BrianTheLion

+1

En 2017 .tostring() ya no es compatible, use .tobytes() en su lugar – ksopyla