10

how i can get md5 of the pil object without saving to file ?

    imq.save('out.png')
    hash =  hashlib.md5(open('out.png','rb').read()).hexdigest()
Artyom
  • 2,863
  • 3
  • 20
  • 15

4 Answers4

17

Actually there is simpler solution:

hashlib.md5(img.tostring()).hexdigest()
alexgula
  • 336
  • 2
  • 4
5

Turning @Ignacio's answer into code, using this answer to help:

import StringIO, hashlib

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

As the referenced other answer notes, this might lead to a KeyError if PIL tries to automatically detect the output format. To avoid this problem you can specify the format manually:

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

(Note: I've used "img" as the variable, rather than your "imq" which I assumed was a typo.)

Community
  • 1
  • 1
Peter Hansen
  • 21,046
  • 5
  • 50
  • 72
  • When I try to save to either a `StringIO` or `BytesIO` object I get a `KeyError` because the format cannot be inferred; providing a known format yields different errors. – FluxIX Apr 04 '17 at 15:24
  • @FluxIX avoid the KeyError with kwargs format='foo' (as you probably did). You'd have to describe the "different errors" for anyone to help with that. – Peter Hansen Apr 04 '17 at 16:36
  • I wasn't asking for help with the different errors, just specifying the parameter as a keyworded argument. – FluxIX Apr 04 '17 at 22:20
  • @FluxIX okay, I've included the warning that the referenced other answer provided, for clarity. I thought your "providing a known format yields different answers" meant the solution still didn't work for you even with that. (Now I don't know what to think... does this work for you or not?) – Peter Hansen Apr 05 '17 at 15:16
  • 1
    Specifying the parameter as a keyworded argument did work. – FluxIX Apr 06 '17 at 03:30
4

You could write it to a StringIO instead, and then take the hash of that.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
2

You could use the following PIL Image class method to get the raw image data to feed to md5().

im.getdata() => sequence

Returns the contents of an image as a sequence object containing pixel values. The sequence object is flattened, so that values for line one follow directly after the values of line zero, and so on.

Note that the resulting MD5 hash of using this won't be the same as your sample code because it is (at least partially) independent of the particular image file format used to save the image. It could be useful if you wanted to compare actual images independent of the particular image file format they may be saved in.

To use it you would need to store the MD5 hash of the image data somewhere independent of any image file where it could be retrieved when needed -- as opposed to generating it by reading the entire file into memory as binary data like the code in your question does. Instead you would need to always load the image into PIL and then use the getdata() method on it to compute hashes.

martineau
  • 119,623
  • 25
  • 170
  • 301