如何使用Python的 PIL模块将EXIF数据写入JPG文件?
在Ubuntu 20.04的 Python 3.8环境中,使用PIL.Image版本7.0.0时,我在将EXIF数据写入新文件的过程中遇到了问题。
我尝试使用(可能略作修改的)EXIF数据(即标签306 “DateTime”)来写入一个新的jpg文件。然而从新文件中读取EXIF数据时,显然存在问题,数据被明显错误地填充。见下文:
原始标签:
36867 : DateTimeOriginal : 2003:01:12 03:04:15
36868 : DateTimeDigitized : 2003:01:12 03:04:15
306 : DateTime : 2003:01:12 03:04:15
新文件的标签(使用未修改的EXIF数据):
36867 : DateTimeOriginal : 3:04:152003:01:12 0
36868 : DateTimeDigitized : 3:04:152003:01:12 0
306 : DateTime : ´2003:01:12 0
可以看到标签306缺失的尾部 '3:04:14' 出现在其他标签的前缀中。这种行为在来自不同来源的JPEG文件中都会出现。
我使用的完整测试代码如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import PIL.Image
import PIL.ExifTags
def fingerExifAndSave(source,target):
im=PIL.Image.open(source)
imexif=im.getexif()
if False : # False True
print("Change tag 306 (DateTime) to something wired for debugging")
imexif[306] = 'abcdefghijklmnopqrs' # tag 306 means "DateTime"
imexif[306] = '2066:55:44 33:22:11'
print(" Tag 306 is now set to :",imexif[306] )
else:
print("NO MODIFICATION TO TAG 306 ('DateTime')!")
# Due to "/usr/lib/p*3/dist*/PIL/TiffImagePlugin.py:588: UserWarning: \
# Metadata Warning, tag 282 had too many entries: 2, expected 1 "
if False : # False True
print("Repairing something for some unknown reason due to warning")
for r in (282,283): imexif[r]= imexif[r][0]
else:
print("NO REAPIRING TO TAGS (282,283)!")
rc=im.save(target, exif=imexif) # Save using the optionally modified EXIF
print("Image written to:",target," with rc =",rc )
im.close()
imexif=None
def showSomeExifTags(myfile):
showThisTags=[306,36867,36868,305] # 'DateTime'-entries and 'Software'
im=PIL.Image.open(myfile)
imexif=im.getexif()
print("\nSome EXIF-tags from '"+myfile+"' (among other):")
print("KeyNr : KeyName"+" "*21+": Value")
for k,v in imexif.items():
if k in showThisTags:
if len(str(v)) > 30 : v=str(v[0:20])+"..." # keep it smooth
print(f"{k:>5} : {PIL.ExifTags.TAGS[k]:27} : {v}")
im.close()
print()
def main():
source="./orig2.jpg" # "./orig2.jpg"
target="./modified.jpg"
print ("PIL.Image.__version__ in use:",PIL.Image.__version__)
showSomeExifTags(source)
fingerExifAndSave(source,target)
showSomeExifTags(target)
if __name__ == "__main__":
main()
我是不是做错了什么?如果是,应该如何正确地做?
在网上搜索时,是否有我错过的已知漏洞?
如何绕过这个问题?
解决方案
我在基于Ubuntu 24.04的 Linux Mint 22上,用不同的 pillow 版本进行了测试。
在 Python 3.8.20 上
7.0.0、7.1.0、7.1.1、7.1.2—— 也会出现同样的问题。7.2.0、8.0.0—— 可以正常工作。
你需要将模块更新到 7.2.0。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。