使用PIL调整图像大小(创建缩略图)时,如何保留图像的EXIF数据?

27

当我尝试使用PIL调整(生成缩略图)图片的大小时,exif数据会丢失。

我该怎么做才能在缩略图中保留exif数据?我查找了相关链接,但似乎都不能起作用。

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")

原始图像具有exif数据,但图像im(512_a.JPEG)没有。

4个回答

23

我阅读了一些源代码,并找到了一种方法,以确保 Exif 数据与缩略图一起保存。

当你在 PIL 中打开一个 jpg 文件时,Image 对象有一个名为info的属性,它是一个字典。其中一个键被称为exif,它有一个值,该值是一个字节字符串 - 来自图像的原始 Exif 数据。你可以将这个字节字符串传递给保存方法,它应该会将 Exif 数据写入新的 jpg 文件:

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)

要获取可读的exif数据版本,您可以按照以下步骤进行操作:
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)

尝试使用“print exif”确认是否存在exif数据。或者您可以尝试运行第二个示例以查看exif数据。 - Gary Kerr
当我使用“Phatch Image Inspector”打开原始文件时,会有exif数据。但是当我使用上述工具打开调整大小的图像文件时,没有exif。 - Jisson
1
我已经有解决方案了。导入pyexiv2库,读取文件元数据,并获取它的缩略图,将其设置为指定文件路径下的512_a,并且最终写入元数据。 - Jisson
1
但是ImageLength和ImageWidth是exif数据的一部分,它们现在不会不正确吗? - jMyles
im.save('P4072956_thumb.jpg', exif=exif)不会写入exif信息。 - 8bitjunkie
显示剩余4条评论

21

在我的项目中,我遇到了和你一样的问题。在搜索谷歌后,我找到了piexif库。它可以帮助Pilowexif数据保存到缩略图中。

您可以使用以下源代码:

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)

注意:我正在使用Python 3.4和Ubuntu 14.04。


2
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()

现在我使用(Patch Image Inspector)打开图像,我可以看到exif数据。

0
这适用于Python 3.11和Pillow 9.4。您可以使用Image.getexif()获取EXIF数据,并在保存图像时将结果传递给Image.save()。以下是一个示例实现:
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)

请注意,其他的图像处理工具,比如"mogrify",不会调整高度/宽度的EXIF数据,甚至可能不建议这样做,但如果你想要这样做的话,可以按照以下步骤进行操作:在exif = original_image.getexif()之后插入以下代码:
    exif.update({
        256: target_width,
        257: target_height,
        })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接