pyexiv2读取IPTC元数据报'utf-8' codec can't decode错误如何解决?
根因说明
该错误是因为待读取图片的IPTC元数据未使用UTF-8编码存储,报错信息中的0xdf字节对应ISO-8859-1(Latin-1)编码下的德语字符ß,py3exiv2默认强制用UTF-8解码非UTF-8编码的元数据,就会触发该解码异常。
可用解决方案
方案1:全局指定IPTC编码
如果你的所有待处理文件的IPTC元数据都是用同一种非UTF-8编码存储,直接在读取元数据前全局设置默认编码即可:
import pyexiv2 # 可根据实际编码替换为cp1252等,西欧语言通用iso-8859-1 pyexiv2.utils.set_default_encoding('iso-8859-1') # 后续执行你原有的逻辑即可 file_meta = pyexiv2.ImageMetadata(file_path) file_meta.read() print(file_meta["Iptc.Application2.Keywords"])
方案2:修改库源码适配多编码场景
如果不同文件的IPTC编码不统一,可以直接修改py3exiv2的解码逻辑,添加错误兼容:
找到你Python环境下的pyexiv2/iptc.py文件,定位到报错对应的第111行附近代码,修改如下:
# 替换原代码:tag._raw_values = _tag._getRawValues() raw_values = _tag._getRawValues() processed_values = [] for val in raw_values: if isinstance(val, bytes): # 优先尝试utf8解码,失败则用latin1解码,也可根据需要调整解码优先级 try: processed_val = val.decode('utf-8') except UnicodeDecodeError: processed_val = val.decode('iso-8859-1') processed_values.append(processed_val) else: processed_values.append(val) tag._raw_values = processed_values
如果不需要保留原始特殊字符,也可以直接用decode('utf-8', errors='replace')把无法解码的字符替换为占位符,逻辑更简单。
方案3:更换元数据处理库
如果不想修改第三方库源码,可以换用Pillow等库自行读取原始元数据后手动解码:
from PIL import Image from PIL.ExifTags import IPTC img = Image.open(file_path) iptc_ifd = img.getexif().get_ifd(IPTC) raw_keywords = iptc_ifd.get(IPTC.Application2.Keywords, []) # 手动指定编码解码 keywords = [kw.decode('iso-8859-1') for kw in raw_keywords] print(keywords)
内容的提问来源于stack exchange,提问作者bugZ
相关产品推荐
相关产品推荐

