I'd like to replace the thumbnail in an image file's EXIF. I've tried several libraries: exif, piexif, Pillow/PIL, none were able to write the thumbnail to the EXIF.
Few examples from what I've tried so far:
import piexif
from PIL import Image
import exif
def replaceThumbnailMode1(sourceImageFilePath, targetImageFilePath):
exifImage = exif.Image(sourceImageFilePath)
thumbnailBytes = exifImage.get_thumbnail()
piexif_dict = piexif.load(targetImageFilePath)
piexif_dict["thumbnail"] = thumbnailBytes
piexif_dict["1st"][513] = 1 # JPEGInterchangeFormat
piexif_dict["1st"][514] = 1 # JPEGInterchangeFormatLength
piexif_bytes = piexif.dump(piexif_dict)
piexif.remove(targetImageFilePath)
piexif.insert(piexif_bytes, targetImageFilePath)
def replaceThumbnailMode2(sourceImageFilePath, targetImageFilePath):
exifImage = exif.Image(sourceImageFilePath)
thumbnailBytes = exifImage.get_thumbnail()
piexif_dict = piexif.load(targetImageFilePath)
piexif_dict["thumbnail"] = thumbnailBytes
piexif_dict["1st"][513] = 1 # JPEGInterchangeFormat
piexif_dict["1st"][514] = 1 # JPEGInterchangeFormatLength
piexif_bytes = piexif.dump(piexif_dict)
im = Image.open(targetImageFilePath)
im.save(targetImageFilePath + "2.jpg", exif = piexif_bytes)
sourceImageFilePath = "source_image.jpg"
targetImageFilePath = "target_image.jpg"
replaceThumbnailMode1(sourceImageFilePath, targetImageFilePath)
# replaceThumbnailMode2(sourceImageFilePath, targetImageFilePath)
What I've noted is that after loading the piexif_bytes with piexif.load(), in the returned exif_dict the JPEGInterchangeFormat, JPEGInterchangeFormatLength TAGs have seemingly correct / calculated values.
Please let me know what should I do differently. I don't know what I'm missing. Worths noting that I'm new to Python, sorry if I'm asking something basic.
UPDATE
I've tried the following and observed that the 2 dictionaries do not match: values for JPEGInterchangeFormat and JPEGInterchangeFormatLength in piexif_dict_from_bytes are way smaller compared to piexif_dict_from_image. For JPEGInterchangeFormat the value is around 1500, whereas it has a value of around 42 000 in piexif_dict_from_image:
def piexif_dict_test(sourceImageFilePath):
piexif_dict_from_image = piexif.load(sourceImageFilePath)
piexif_bytes = piexif.dump(piexif_dict_from_image)
piexif_dict_from_bytes = piexif.load(piexif_bytes)
print
pixeif.transplant() on the other hand, correctly copies the thumbnail from one image to the other, but I want to set a new one.
Currently I'm stuck. I'll try to find another library which does the job, if there will be no solution for piexif.
This code works fine. You probably missed out on some exif required data that is essential. Try this:
If not, look at the exif2 standard: https://exiv2.org/tags.html