Reputation: 3725
When I try to resize (thumbnail) an image using PIL, the exif data is lost.
What do I have to do preserve exif data in the thumbnail image? When I searched for the same, got some links but none seem to be working.
from PIL import Image
import StringIO
file_path = '/home/me/img/a.JPG'
im = Image.open( file_path)
THUMB_SIZES = [(512, 512)]
for thumbnail_size in THUMB_SIZES:
im.thumbnail( thumbnail_size, Image.ANTIALIAS)
thumbnail_buf_string = StringIO.StringIO()
im.save('512_' + "a", "JPEG")
The orginal image has exif data, but image im(512_a.JPEG) doesn't.
Upvotes: 30
Views: 22757
Reputation: 3504
This works with Python 3.11 and Pillow 9.4. You can retrieve the EXIF data with Image.getexif()
and hand over the result to Image.save()
when saving the image. Here is an example implementation:
from PIL import Image
def resize_image(input_path, output_path, target_height, quality=80):
"""
Resize an image given it's target height, adjusting the width to keep the
aspect ratio, while preserving the EXIF data in the modified image.
"""
original_image = Image.open(input_path)
aspect_ratio = original_image.width / original_image.height
target_width = int(target_height * aspect_ratio)
resized_image = original_image.resize((target_width, target_height))
exif = original_image.getexif()
resized_image.save(output_path, quality=quality, exif=exif)
Note that other image manipulation tools like "mogrify" don't adjust the height/width EXIF data, it might even not be advised to do so, but in case you want to, here is how it could be done: After exif = original_image.getexif()
, insert:
exif.update({
256: target_width,
257: target_height,
})
Upvotes: 2
Reputation: 14430
I read throught some of the source code and found a way to make sure that the exif data is saved with the thumbnail.
When you open a jpg file in PIL, the Image
object has an info
attribute which is a dictionary. One of the keys is called exif
and it has a value which is a byte string - the raw exif data from the image. You can pass this byte string to the save method and it should write the exif data to the new jpg file:
from PIL import Image
size = (512, 512)
im = Image.open('P4072956.jpg')
im.thumbnail(size, Image.ANTIALIAS)
exif = im.info['exif']
im.save('P4072956_thumb.jpg', exif=exif)
To get a human-readable version of the exif data you can do the following:
from PIL import Image
from PIL.ExifTags import TAGS
im = Image.open('P4072956.jpg')
for k, v in im.getexif().items():
print(TAGS.get(k, k), v)
Upvotes: 24
Reputation: 3725
import pyexiv2
from PIL import Image
file_path = '/home/../img/a.JPG'
metadata = pyexiv2.ImageMetadata(file_path)
metadata.read()
thumb = metadata.exif_thumbnail
thumb.set_from_file(file_path)
thumb.write_to_file('512_' + "a")
thumb.erase()
metadata.write()
Now I open the image using (Patch Image Inspector) , I can see the exif data
Upvotes: 2
Reputation: 5376
In my project, i met the same issue with you. After searching Google, I found piexif
library. It help to Pilow
save exif
data to thumbnails.
You can use the source code below:
from PIL import Image
import piexif
import StringIO
file_path = '/home/me/img/a.JPG'
im = Image.open( file_path)
# load exif data
exif_dict = piexif.load(im.info["exif"])
exif_bytes = piexif.dump(exif_dict)
THUMB_SIZES = [(512, 512)]
for thumbnail_size in THUMB_SIZES:
im.thumbnail( thumbnail_size, Image.ANTIALIAS)
thumbnail_buf_string = StringIO.StringIO()
# save thumbnail with exif data
im.save('512_' + "a", "JPEG", exif=exif_bytes)
Note: I am using python 3.4 and ubuntu 14.04
Upvotes: 22