Timur U
Timur U

Reputation: 445

Python 3 Sha256 of Pillow image and identify -verbose do not equal

Good day!

I can to get sha256 hash for some file using ImageMagick:

$ identify -verbose z.png | rg signature
$ signature: 07f130a92bd1e7a2d3d0c6c8e143cddd3a767cdd365cd055317434ff8197c1a8

But when I use Pillow on Python 3:

from PIL import Image
im = Image.open('z.png')

import hashlib
sha=hashlib.sha256(im.tobytes()).hexdigest()
print(sha,'sha256')

>>> 4b705fbc8d6979fdc9a94335a8cf4b870c2424381fd983ec0d520a7383eba994 sha256

Program version:

Version: ImageMagick 7.1.0-27 Q16-HDRI arm 2022-03-04 https://imagemagick.org
Python 3.9.10
Pillow 9.0.0

How can I get equal results? And why they are different?

Upvotes: 0

Views: 498

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 207335

I'm not sure about this answer and have no access to a machine to test it for a few days. However, if you look at the version string of your ImageMagick installation, you will see it is Q16 which means ImageMagick holds each sample in a 16-bit unsigned integer, whereas PIL will be using 8-bit integers for each sample.

I think the solution is probably either to map ImageMagick's pixels down to 8-bits, or maybe map PIL's pixels up to 16-bits.

To map ImageMagick's pixels down, I think you would need something like:

magick stream -map rgb -storage-type character YOURIMAGE - | sha256sum

Or maybe:

magick YOURIMAGE -depth 8 rgb:- | sha256sum

Going the other way, and scaling PIL's 8-bit unsigned up to 16-bit, I imagine you'd want something like:

Im = Image.open(YOURIMAGE).convert('RGB')
Na = np.array(im).astype(np.uint16))

Then you can use:

sha=hashlib.sha256(Na.tobytes()).hexdigest()

Thinking about this a little further, you may have fundamental issues if your PNG images are 16-bit RGB(A) because PIL probably won't load them at all.

Also, I am not sure what happens if your images are palette/indexed images - I don't know if ImageMagick checksums just the indices, or whether it looks up the indices in the palette to make an RGB image and then checksums the result.

Upvotes: 1

Related Questions