使用Python将“Date take”Exif/XMP信息添加到TIF文件中

2024-10-01 05:01:01 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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:\Python37\lib\site-packages\piexif\_insert.py", line 39, in insert
    raise InvalidImageDataError
piexif._exceptions.InvalidImageDataError

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

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

要复制或获取失败tif文件的示例,请克隆我的项目(下面的链接)

详情:

将数千张图片扫描到tif文件后,我想为“拍摄日期”指定EXIF值。我正在编写一个Python脚本来在Windows (BitBucket)中实现这一点,该脚本还将根据从YYYY-MM-DD*开始的预定义文件夹命名约定编辑“创建日期”和“修改日期”。最后两个任务适用于tif文件和jpeg,但EXIF不适用于tif

更新:

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

更新2:

看起来Exif无法处理尼康扫描(2005)中的文件。唯一的选项是将xmp:createdate节点添加到文件中的xmp信息中。 如果有人能告诉我这是如何做到的,无论是用纯Python还是在Windows上调用Python中的一个单独的工具,这都是值得的


Tags: 文件信息编辑datebytes节点windowsfilename
2条回答

根据Piexif documentationpiexif.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)

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

  • 进出口银行
  • exifread
  • 皮耶西夫
  • 枕头
  • 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,因为它需要更少的代码,并且不会丢失原始文件中的一些细节

相关问题 更多 >