如何使用Python向EXIF标签写入非Latin1字符?Pillow与piexif编码问题求助
解决piexif处理EXIF特殊字符的编码问题
这个编码坑我之前踩过,确实挺闹心的。先给你理清楚前因后果,再给你几个可行的解决方案:
为什么会出现这个错误?
EXIF标准里,传统的IFD0标签(比如你用到的Artist,标签号315)默认是用Latin-1编码存储的,piexif写入时严格遵循这个规则,所以像œ这种超出Latin-1范围的字符就会触发编码错误。
那为什么Windows资源管理器手动添加后piexif能读取?因为Windows其实是“违规”用了UTF-16LE编码来存储这些特殊字符,还加了字节顺序标记(BOM),piexif读取的时候能识别这种情况并自动解码,但写入的时候没做这个兼容,所以就卡壳了。
用piexif解决的办法
既然知道了Windows的“小技巧”,我们可以手动把字符串转成UTF-16LE编码并加上BOM,这样既能让piexif正常写入,也能被Windows资源管理器正确识别:
import PIL.Image import piexif img = PIL.Image.open("photo.jpg") exif_dict = piexif.load(img.info["exif"]) # 将特殊字符字符串转为UTF-16LE字节,加上BOM(\xff\xfe) artist_str = "Lebœuf" exif_dict["0th"][315] = b"\xff\xfe" + artist_str.encode("utf-16le") # 注意:保存时需要用piexif.dump把字典转为EXIF字节流 img.save("photo.jpg", "jpeg", exif=piexif.dump(exif_dict))
更省心的替代库
如果不想手动处理编码,推荐几个对Unicode更友好的EXIF处理库:
1. exif库(轻量易用)
这个库封装得很友好,直接支持Unicode字符串,不需要手动转码:
from exif import Image # 读取图片 with open("photo.jpg", "rb") as img_file: img = Image(img_file) # 设置EXIF信息 img.artist = "Lebœuf" img.title = "我的旅行照片" # 标题标签也可以直接设置 # 保存修改 with open("photo.jpg", "wb") as img_file: img_file.write(img.get_file())
2. pyexiv2库(功能全面)
如果需要处理更多元数据(比如XMP、IPTC),pyexiv2是个不错的选择,同样原生支持Unicode:
import pyexiv2 # 打开图片 image = pyexiv2.Image("photo.jpg") # 修改EXIF标签,直接传Unicode字符串即可 image.modify_exif({"Exif.Image.Artist": "Lebœuf", "Exif.Image.ImageDescription": "带特殊字符的标题"}) # 别忘了关闭资源 image.close()
内容的提问来源于stack exchange,提问作者Paulo Modulo
相关产品推荐
相关产品推荐

