使用Python PIL 7.0.0写入JPG文件EXIF数据时出现内容错位/截断问题的求助
使用Python PIL 7.0.0写入JPG文件EXIF数据时出现内容错位/截断问题的求助
我在Ubuntu 20.04系统上,使用Python 3.8和PIL.Image 7.0.0版本时,遇到了写入EXIF数据到新JPG文件的异常问题。
当我尝试提取原图片的EXIF数据(未修改或仅修改DateTime标签)并写入新文件后,读取新文件的EXIF会发现标签内容出现错位/截断:原标签丢失的部分内容会跑到其他标签中作为前缀,或者自身内容被截断。这种现象在不同来源的JPG图片中都会出现。
原图片与新文件的EXIF对比
原图片的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关键标签(未修改原EXIF数据)
36867 : DateTimeOriginal : 3:04:152003:01:12 0 36868 : DateTimeDigitized : 3:04:152003:01:12 0 306 : DateTime : ´2003:01:12 0
可以看到,DateTime标签(306)丢失的尾部3:04:14出现在了其他标签的前缀位置,内容完全混乱。
完整测试代码
我使用的测试代码如下:
#!/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 : # 切换为True可测试修改DateTime标签的场景 print("Change tag 306 (DateTime) to something wired for debugging") imexif[306] = 'abcdefghijklmnopqrs' # tag 306 对应 "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')!") # 处理TiffImagePlugin.py的警告:Metadata Warning, tag 282 had too many entries: 2, expected 1 if 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) # 保存时写入提取到的EXIF数据 print("Image written to:",target," with rc =",rc ) im.close() imexif=None def showSomeExifTags(myfile): showThisTags=[306,36867,36868,305] # 关注DateTime相关标签和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])+"..." # 截断过长内容方便显示 print(f"{k:>5} : {PIL.ExifTags.TAGS[k]:27} : {v}") im.close() print() def main(): source="./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()
我的疑问
- 是不是我在处理EXIF数据的过程中存在错误?正确的处理方式应该是什么?
- 这是不是PIL 7.0.0版本的已知Bug?
- 有没有临时的解决办法可以绕过这个问题?




