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