I have to store a huge quantity of scientific images generated by a robotic microscope. During the storing process I would like to store in the Exif metadata also a hash of the image data so to make every image identifiable and to determine if it was modified afterward. The image data comes as a 2d array of 16bit uint. The code I'm attempting to use is:
import math,png,io,hashlib, numpy as np
import piexif
import piexif.helper
from PIL import Image
def MOEDAL_IMGWR_JPG_h(img,fname,q,js='{}',exif_ifd ={}):
y=np.asarray(img);
z = (65535*((y - y.min())/y.ptp())).astype(np.uint16)
a=(np.array(z)//256).astype("uint8");
im = Image.fromarray(a)
im.save(fname, format='JPEG', quality=q) # save the image
im=Image.open(fname) # reload it
img_byte_arr = io.BytesIO()
im.save(img_byte_arr,format='PNG') # write the image content in memory
jdc=json.loads(js)
jdc['sha244']=hashlib.sha224(img_byte_arr.getvalue()).hexdigest()
a=json.dumps(jdc)
exif_dict = {"Exif":exif_ifd}
exif_dict["Exif"][piexif.ExifIFD.UserComment] = piexif.helper.UserComment.dump(a)
exif_bytes = piexif.dump(exif_dict)
piexif.insert(exif_bytes,fname) # This method is supposed to work (but does not)
# im.save(fname, exif=exif_bytes) #
As you can see I try to reload the image data after saving the image with the desired compression calculate the hash and store it (as a JSON key) in the UserComment field of the exif metadata.
In the second save I tried to use a compression
But when I try from the Python CLI to reload the image and calculate the hash again I obtain different value.
>>> im=Image.open('Test.jpg')
>>> img_byte_arr = io.BytesIO()
>>> im.save(img_byte_arr,format='PNG')
>>> exif_dict=piexif.load('TEST.jpg')
>>> print(exif_dict)
{'0th': {34665: 26}, 'Exif': {37510: b'ASCII\x00\x00\x00{"sha244": "94ae6bcfbb94c75c8adf65536993a03a107aa076cb94e20ef6bdff12"}'}, 'GPS': {}, 'Interop': {}, '1st': {}, 'thumbnail': None}
>>> hashlib.sha224(img_byte_arr.getvalue()).hexdigest()
'ef5966d665aaefc0d5b48c293957f66007c8dcaab7afc39f85a3964e'
Maybe I'm wrong with the last im.save but I have also tried to specify format='JPEG' and quality=100 so that I would not repeat the compression again. Any suggestions ? Thanks, G.L.