【问题标题】:Resize image in Python without losing EXIF data在 Python 中调整图像大小而不会丢失 EXIF 数据
【发布时间】:2010-09-28 21:13:47
【问题描述】:

我需要使用 Python 调整 jpg 图像的大小,而不会丢失原始图像的 EXIF 数据(有关拍摄日期、相机型号等的元数据)。所有关于 python 和图像的谷歌搜索都指向我目前正在使用的 PIL 库,但似乎无法保留元数据。我到目前为止的代码(使用 PIL)是这样的:

img = Image.open('foo.jpg')
width,height = 800,600
if img.size[0] < img.size[1]:
    width,height = height,width

resized_img = img.resize((width, height), Image.ANTIALIAS) # best down-sizing filter
resized_img.save('foo-resized.jpg')

有什么想法吗?或者我可以使用的其他库?

【问题讨论】:

标签: python image-processing python-imaging-library exif


【解决方案1】:

实际上有一种非常简单的方法可以仅使用 PIL 将 EXIF 数据从一张图片复制到另一张图片。虽然它不允许修改 exif 标签。

image = Image.open('test.jpg')
exif = image.info['exif']
# Your picture process here
image = image.rotate(90)
image.save('test_rotated.jpg', 'JPEG', exif=exif)

如您所见,save 函数可以使用 exif 参数,该参数允许在保存时将原始 exif 数据复制到新图像中。如果您只想这样做,您实际上不需要任何其他库。我似乎找不到关于保存选项的任何文档,我什至不知道这是否特定于 Pillow 或与 PIL 一起使用。 (如果有人有某种链接,我会很高兴他们将其发布在 cmets 中)

【讨论】:

  • 谢谢,正是我想要的。在 Pillow 文档中并没有真正明确。为了修改 exif 标签,我在保存的文件上使用 GExiv2。
  • 这确实有效,不知道为什么不对简单任务进行更多讨论,因为其他库可能很难添加到不同的操作系统环境。
  • 这很棒。谢谢你。它按我希望的那样工作。
【解决方案2】:
import jpeg
jpeg.setExif(jpeg.getExif('foo.jpg'), 'foo-resized.jpg') 

http://www.emilas.com/jpeg/

【讨论】:

【解决方案3】:

您可以使用 pyexiv2 从源图像中复制 EXIF 数据。在以下示例中,使用 PIL 库调整图像大小,使用 pyexiv2 复制的 EXIF 数据和图像大小 EXIF 字段设置为新大小。

def resize_image(source_path, dest_path, size):
    # resize image
    image = Image.open(source_path)
    image.thumbnail(size, Image.ANTIALIAS)
    image.save(dest_path, "JPEG")

    # copy EXIF data
    source_image = pyexiv2.Image(source_path)
    source_image.readMetadata()
    dest_image = pyexiv2.Image(dest_path)
    dest_image.readMetadata()
    source_image.copyMetadataTo(dest_image)

    # set EXIF image size info to resized size
    dest_image["Exif.Photo.PixelXDimension"] = image.size[0]
    dest_image["Exif.Photo.PixelYDimension"] = image.size[1]
    dest_image.writeMetadata()

# resizing local file
resize_image("41965749.jpg", "resized.jpg", (600,400))

【讨论】:

  • 哪个版本的pyexiv2?版本越早,出现“copyMetadataTo”的可能性就越小。我使用的是 Ubuntu 8.04,没有这个方法,V0.1.1。
  • 对于在pyexiv2 0.3版下工作的解决方案(作者宣布项目停止之前的最后一个),请参阅stackoverflow.com/a/18318254/1017348
【解决方案4】:

为什么不使用ImageMagick
它是一个相当标准的工具(例如,它是 Gallery 2 使用的标准工具);我从未使用过它,但它也有一个python interface(或者,您也可以简单地生成命令),最重要的是,应该在所有转换之间维护 EXIF 信息。

【讨论】:

  • 碰巧PIL是python中的标准工具,所以ImageMagick python绑定不是很好。
  • 在这种情况下,我会生成一个单独的进程。 ImageMagick(作为可执行文件)几乎适用于所有配置。
  • ImageMagick 绑定到 Python 的问题不是可用性,而是缺乏文档。
【解决方案5】:

这是截至 2018 年的更新答案。piexif 是一个纯 python 库,对我来说,它可以通过 pip (pip install piexif) 轻松安装并且运行良好(感谢维护者!)。 https://pypi.org/project/piexif/

用法很简单,一行会复制接受的答案并将所有EXIF标签从原始图像复制到调整大小的图像:

import piexif
piexif.transplant("foo.jpg", "foo-resized.jpg")

我还没有尝试过,但看起来您也可以使用链接文档中描述的加载、转储和插入功能轻松执行修改。

【讨论】:

  • 这是本页的最佳答案。它运行良好,并且只需一行简单的代码。
  • 这确实是最好的答案!!谢谢@biomiker
【解决方案6】:

对于 pyexiv2 v0.3.2,API documentation 是指将 EXIF 数据从一个图像传递到另一个图像的复制方法。在这种情况下,它将是原始图像的 EXIF 数据到调整大小的图像。

离开@Maksym Kozlenko,复制EXIF数据的更新代码是:

    source_image = pyexiv2.ImageMetadata(source_path)
    source_image.read()

    dest_image = pyexiv2.ImageMetadata(dest_path)
    dest_image.read()

    source_image.copy(dest_image,exif=True)
    dest_image.write()

【讨论】:

    【解决方案7】:

    保存后可以使用pyexiv2修改文件。

    【讨论】:

      【解决方案8】:
      from PIL import Image
      img_path = "/tmp/img.jpg"
      img = Image.open(img_path)
      exif = img.info['exif']
      img.save("output_"+img_path, exif=exif)
      

      在 Pillow 2.5.3 中测试

      【讨论】:

        【解决方案9】:

        @Depado 的解决方案似乎对我不起作用,在我的场景中,图像甚至不包含 exif 段。

        pyexiv2 很难在我的 Mac 上安装,而是使用模块 pexif https://github.com/bennoleslie/pexif/blob/master/pexif.py。为了向不包含 exif 信息的图像“添加 exif 段”,我添加了包含在拥有 exif 段的图像中的 exif 信息

        from pexif import JpegFile
        
        #get exif segment from an image
        jpeg = JpegFile.fromFile(path_with_exif)
        jpeg_exif = jpeg.get_exif()
        
        #import the exif segment above to the image file which does not contain exif segment
        jpeg = JpegFile.fromFile(path_without_exif)
        exif = jpeg.import_exif(jpeg_exif)
        jpeg.writeFile(path_without_exif)
        

        【讨论】:

          【解决方案10】:

          Maksym Kozlenko 的更新版本 Python3 和py3exiv2 v0.7

          # Resize image and update Exif data
          from PIL import Image
          import pyexiv2
          
          def resize_image(source_path, dest_path, size):
              # resize image
              image = Image.open(source_path)
              # Using thumbnail, then 'size' is MAX width or weight
              # so will retain aspect ratio
              image.thumbnail(size, Image.ANTIALIAS)
              image.save(dest_path, "JPEG")
          
              # copy EXIF data
              source_exif = pyexiv2.ImageMetadata(source_path)
              source_exif.read()
              dest_exif = pyexiv2.ImageMetadata(dest_path)
              dest_exif.read()
              source_exif.copy(dest_exif,exif=True)
          
              # set EXIF image size info to resized size
              dest_exif["Exif.Photo.PixelXDimension"] = image.size[0]
              dest_exif["Exif.Photo.PixelYDimension"] = image.size[1]
              dest_exif.write()
          

          【讨论】:

            【解决方案11】:

            PIL 处理 EXIF 数据,不是吗?查看 PIL.ExifTags。

            【讨论】:

            • resize() 删除EXIF信息,没有办法放回PIL,AFAICT。可以用img._getexif()获取数据,但是resize之后这个方法就不存在了
            猜你喜欢
            • 2010-11-16
            • 1970-01-01
            • 2011-01-20
            • 1970-01-01
            • 2014-09-20
            • 2011-04-18
            • 2015-03-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多