Jisson
Jisson

Reputation: 3725

Preserve exif data of image with PIL when resize(create thumbnail)

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

Answers (4)

Iodnas
Iodnas

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

Gary Kerr
Gary Kerr

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

Jisson
Jisson

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

Nguyen Sy Thanh Son
Nguyen Sy Thanh Son

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

Related Questions