使用Python读取JPG拍摄时间元数据部分文件失败的问题
问题原因与解决方法
问题原因
你的问题根源在于Pillow(PIL)的EXIF解码逻辑局限性:尼康D3100相机可能使用了非UTF-8编码(比如Shift-JIS)存储部分EXIF元数据(例如相机内部注释、特定自定义字段),而Pillow在读取这些字段时默认强制用UTF-8解码,遇到不符合UTF-8规则的字节(如错误信息中的0xea)就触发UnicodeDecodeError。
你当前的代码遍历所有EXIF标签,一旦碰到编码错误的字段就直接崩溃,根本没机会读取到拍摄时间对应的DateTimeOriginal标签。而Windows资源管理器采用了更兼容的编码适配逻辑,所以能正常解析并显示拍摄时间。
解决方法
方法1:直接读取目标EXIF标签(推荐)
无需遍历所有标签,直接定位到拍摄时间对应的标签ID(36867,对应DateTimeOriginal),避开编码错误的字段:
from PIL import Image from PIL.ExifTags import TAGS def get_date_of_JPG(path): image = Image.open(path) exifdata = image.getexif() # 拍摄时间对应的EXIF标签ID为36867(DateTimeOriginal) date_tag_id = 36867 if date_tag_id in exifdata: return exifdata.get(date_tag_id) return "no Date"
方法2:捕获解码错误,跳过问题字段
如果需要遍历所有标签,在读取字段时捕获UnicodeDecodeError,手动处理二进制数据:
from PIL import Image from PIL.ExifTags import TAGS def get_date_of_JPG(path): image = Image.open(path) exifdata = image.getexif() date_time = "no Date" for tag_id in exifdata: tag = TAGS.get(tag_id, tag_id) try: data = exifdata.get(tag_id) if tag == "DateTimeOriginal": date_time = data print(f"{tag}: {data}") except UnicodeDecodeError: # 尝试用尼康常用的Shift-JIS编码解码二进制数据 raw_data = exifdata.get_raw(tag_id) try: decoded_data = raw_data.decode('shift-jis') print(f"{tag}: {decoded_data}") except: print(f"{tag}: 无法解码的二进制数据: {raw_data}") return date_time
方法3:使用更健壮的EXIF处理库
如果Pillow的表现仍不理想,可以切换到exifread库,它对非标准编码的兼容性更好:
先安装库:
pip install exifread
再使用以下代码:
import exifread def get_date_of_JPG(path): with open(path, 'rb') as f: tags = exifread.process_file(f) # 拍摄时间对应的标签名称为"EXIF DateTimeOriginal" date_tag = 'EXIF DateTimeOriginal' if date_tag in tags: return str(tags[date_tag]) return "no Date"
内容的提问来源于stack exchange,提问作者Mart Prenger
相关产品推荐
相关产品推荐

