使用Pillow提取奥林巴斯相机照片EXIF时报invalid continuation byte错误如何解决
问题原因
你代码的报错是因为默认所有bytes类型的EXIF字段都是UTF-8编码的文本,但实际EXIF规范中很多字段是二进制结构数据(比如你遇到的PrintImageMatching是相机厂商定义的打印匹配二进制数据,GPSInfo、厂商自定义MakerNote等也都是二进制类型),强行用UTF-8解码必然会出错。
修复方案(无需更换Pillow模块)
方案1:快速兼容修复
给解码逻辑添加错误处理参数,遇到无法解码的字节时自动替换/忽略,不会中断程序运行:
from PIL import Image from PIL.ExifTags import TAGS imagename = "path to file" image = Image.open(imagename) exifdata = image.getexif() for tagid in exifdata: tagname = TAGS.get(tagid, tagid) data = exifdata.get(tagid) if isinstance(data, bytes): # 替换无法解码的字符,不会抛出错误 data = data.decode('utf-8', errors='replace').strip() print(f"{tagname:25}: {data}")
如果不需要保留异常字节的占位,也可以把errors='replace'改成errors='ignore'直接删除无法解码的字节。
方案2:精准解码(推荐)
仅对明确为文本类型的EXIF字段做解码,二进制类型字段直接保留原始格式:
from PIL import Image from PIL.ExifTags import TAGS # 明确为文本类型的EXIF标签列表 TEXT_TAGS = { "ImageDescription", "Make", "Model", "Software", "DateTime", "Copyright", "Artist", "DateTimeOriginal", "DateTimeDigitized", "UserComment", "HostComputer" } imagename = "path to file" image = Image.open(imagename) exifdata = image.getexif() for tagid in exifdata: tagname = TAGS.get(tagid, tagid) data = exifdata.get(tagid) if isinstance(data, bytes) and tagname in TEXT_TAGS: data = data.decode('utf-8', errors='replace').strip() print(f"{tagname:25}: {data}")
补充说明
如果你需要解析奥林巴斯相机的私有二进制字段内容,才需要额外安装专门的EXIF解析库如pyexiv2、exifread,普通的通用EXIF提取需求用Pillow完全可以满足。
内容的提问来源于stack exchange,提问作者Harrison G
相关产品推荐
相关产品推荐

