2010-11-27 5 views
6

comment puis-je obtenir md5 de l'objet pil sans enregistrer dans le fichier?md5 de l'objet pil

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

Répondre

4

Vous pouvez écrire à un StringIO au lieu, puis prendre le hachage de cela.

1

Vous pouvez utiliser la méthode de classe PIL Image suivante pour obtenir les données d'image brutes à nourrir à md5().

im.getdata() => séquence

retourne le contenu d'une image comme un objet de séquence contenant des valeurs pixel. L'objet de séquence est aplati, de sorte que les valeurs de la première ligne suivent directement les valeurs de ligne zéro, et ainsi de suite.

Notez que le hachage MD5 résultant de l'utilisation de cette ne sera pas être le même que votre exemple de code parce qu'il est (au moins partiellement) indépendamment du format de fichier image particulière utilisée pour enregistrer l'image. Cela peut être utile si vous souhaitez comparer des images réelles indépendamment du format de fichier d'image particulier dans lequel elles peuvent être enregistrées.

Pour l'utiliser, vous devez stocker le hachage MD5 des données d'image quelque part indépendamment de tout fichier d'image où il peut être récupéré en cas de besoin - par opposition à la génération en lisant le fichier entier en mémoire comme des données binaires comme le code dans votre question. Au lieu de cela, vous devrez toujours charger l'image dans PIL, puis utiliser la méthode getdata() pour calculer les hachages.

5

Turning @ réponse de Ignacio en code, en utilisant this answer pour aider:

import StringIO, hashlib 

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

Comme les autres notes de réponse référencés, cela pourrait conduire à une KeyError si PIL essaie de détecter automatiquement le format de sortie. Pour éviter ce problème, vous pouvez spécifier le format manuellement:

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

(Note:. Je l'ai utilisé « img » comme variable, plutôt que votre « IMQ » que je supposais une faute de frappe)

+0

Lorsque je tente de sauver soit un '' StringIO' ou objet BytesIO' je reçois un 'KeyError' parce que le format ne peut pas être déduit; fournir un format connu génère différentes erreurs. – FluxIX

+0

@FluxIX évitez KeyError avec kwargs format = 'foo' (comme vous l'avez probablement fait). Vous devez décrire les "différentes erreurs" pour que quelqu'un puisse vous aider. –

+0

Je ne demandais pas d'aide pour les différentes erreurs, en spécifiant simplement le paramètre comme argument avec mot-clé. – FluxIX

12

en fait, il est plus simple solution:

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

On dirait que .tostring() est obsolète à partir de la version 2.0 en faveur de .tobytes() – BrianTheLion

+1

En 2017, .tostring() n'est plus supporté, utilisez .tobytes() à la place. – ksopyla