使用 Python 将 "Date Taken" Exif/XMP 信息添加到 TIF 文件



在Windows 10上使用以下Python代码,我试图编辑"的EXIF信息;"拍摄日期";使用Nikon Scan 4.0.3(2008年左右的软件(创建的tif图像文件。

import piexif
def setImageDateTakenAttribute(filename, date_taken):
exif_dict = piexif.load(filename)
exif_dict['Exif'] = { 
    piexif.ExifIFD.DateTimeOriginal: datetime.datetime(*date_taken[:6]).strftime("%Y:%m:%d %H:%M:%S") 
} 
exif_bytes = piexif.dump(exif_dict)
piexif.insert(exif_bytes, filename)

这在Python 3中对jpeg文件很有效,但当我尝试使用相同的代码编辑tif文件时,我会收到以下错误:

    setImageDateTakenAttribute(full_path, folder_date)
  File "image-and-movie-bulk-creation-dates.py", line 78, in setImageDateTakenAttribute
    piexif.insert(exif_bytes, filename)
  File "C:Python37libsite-packagespiexif_insert.py", line 39, in insert
    raise InvalidImageDataError
piexif._exceptions.InvalidImageDataError

到目前为止,我一直在寻找其他可能支持我的文件的软件包,但没有成功。

有人知道在Python中如何在不删除现有exif信息和不更改图像格式的情况下进行编辑吗

要复制或获得失败的tif文件的样本,请克隆我的项目(下面的链接(。

详细信息:

在将数千张图片扫描到tif文件之后;拍摄日期";。我正在写一个Python脚本来在Windows(BitBucket(中做到这一点,它还将编辑";创建日期";以及";"修改日期";来自以YYYY-MM-DD*开头的预定义文件夹命名约定。最后两个任务适用于tif文件和jpeg,但EXIF不适用于tif。

更新:

运行exif工具,我得到的输出没有创建日期节点,但在Windows中使用文件属性设置日期后,字段"创建日期";以及";"原始日期/时间";出现。此外,XMP元值的原始文本打印输出在Windows中设置创建日期后提供了一个名为XMP:createdate的添加节点。但我还是不知道如何第一次在文件中创建这些字段。

更新2:

看起来Exif无法处理Nikon Scan(2005(中的文件。唯一的选项是将xmp:createdate节点添加到文件中的xmp信息中。如果有人能向我展示这是如何做到的,无论是在纯Python中,还是通过在Windows上调用Python中的一个单独工具,它都应该得到全额奖励。

这个问题比我最初想的要复杂。在研究过程中,我查看了以下Python模块:

  • exif
  • Exifrad
  • piexif
  • 枕头
  • pyexiv2

有些模块差点修改您想要更改的日期。但最终,我无法使任何模块正常工作。正确是指在不损坏文件的情况下更改日期字段。最后,我将推荐一种不同的方法,它使用子流程和适用于Unix和Windows的外部工具。那个工具是exiftool,我用了很多年了。

import subprocess
from subprocess import check_output
from datatime import datetime
filename = 'Nikon.NEF'
rtn_data = check_output(['exiftool', filename])
print(rtn_data.decode("utf-8"))
# output 
...
Create Date : 2008:10:24 09:12:12.61
...
today = datetime.today()
new_date = today.strftime("%Y:%m:%d %H:%M:%S")
subprocess.call(['exiftool', f'-CreateDate={new_date}', filename])
changed_data = check_output(['exiftool', filename])
print(changed.decode("utf-8"))
# output 
...
Create Date : 2020:11:02 18:43:13
...

exiftool允许您一次性更改任何设置和所有日期。

更新不使用exiftool:

您可以使用piexif,执行此操作,但您必须创建TIFF的副本并将其转换为JPEG。我注意到,当您创建此副本时,一些元数据会丢失,根据您的用例,这可能是不可能的。

import piexif
from PIL import Image
from datetime import datetime
from PIL.ExifTags import TAGS
img = Image.open('test.tiff')
# get metadata
meta_dict = {TAGS[key]: img.tag[key] for key in img.tag.keys()}
exif_bytes = piexif.dump(meta_dict)
# get image height and width 
height = img.height
width = img.width
# resize the image and save it to a new file, which is a JPEG
img.resize((width, height), Image.ANTIALIAS).save('test2.jpeg', "JPEG", exif=exif_bytes, quality="web_high", optimize=True)
today = datetime.today()
new_date = today.strftime("%Y:%m:%d %H:%M:%S")
# load the metadata from the original file
exif_dict = piexif.load("test.tiff")
# change various dates
exif_dict['0th'][piexif.ImageIFD.DateTime] = bytes(new_date, 'utf-8')
exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = bytes(new_date, 'utf-8')
exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = bytes(new_date, 'utf-8')
# dump the changes
exif_bytes = piexif.dump(exif_dict)
# write the changes the the JPEG file
piexif.insert(exif_bytes, 'test2.jpeg')

我仍然更喜欢使用exiftool,因为它占用的代码更少,而且不会丢失原始文件中的一些细节。

根据Piexif文档,piexif.insert方法仅适用于JPEG或WebP文件。另一种选择是使用PIL:将当前exif_bytes保存到替换图像文件中

import piexif
from PIL import Image
def setImageDateTakenAttribute(filename, date_taken):
    img = Image.open(filename)
    exif_dict = piexif.load(filename)
    exif_dict['Exif'] = { 
        piexif.ExifIFD.DateTimeOriginal: datetime.datetime(*date_taken[:6]).strftime("%Y:%m:%d %H:%M:%S") 
    } 
    exif_bytes = piexif.dump(exif_dict)
    img.save(filename, 'tiff', exif=exif_bytes)

最新更新