修改图片EXIF数据时遭遇OverflowError等plum包错误的解决方法
解决Plum包EXIF解析异常的实用方案
1. 针对性捕获异常,避免流程崩溃
直接在循环里捕获Plum相关的异常,跳过损坏文件同时记录错误,不让单个坏文件搞砸整个批量任务:
修改你的循环代码,加入异常处理逻辑:
from plum.exceptions import UnpackError ... for item in your_items: try: full_path = f"{old_source_path}{item.path}" with open(full_path, "rb") as im_file: imexif = Image2(im_file) # 修改EXIF字段 imexif.copyright = "Copyright 2023 somebody. All Rights Reserved." imexif.gps_latitude = decdeg2dms(item.latitude) imexif.gps_longitude = decdeg2dms(item.longitude) imexif.gps_altitude = item.altitude # 别忘了保存修改后的文件 with open(f"{new_target_path}{item.path}", "wb") as out_file: imexif.save(out_file) except UnpackError: print(f"跳过损坏文件:{item.path}(EXIF结构解析失败)") # 把出错路径写入日志,方便后续排查 with open("exif_error_log.txt", "a", encoding="utf-8") as log_f: log_f.write(f"UnpackError: {item.path}\n") except OverflowError: print(f"跳过损坏文件:{item.path}(数值溢出错误)") with open("exif_error_log.txt", "a", encoding="utf-8") as log_f: log_f.write(f"OverflowError: {item.path}\n") except Exception as e: # 兜底捕获其他未知异常 print(f"文件 {item.path} 出现未知错误:{str(e)}") with open("exif_error_log.txt", "a", encoding="utf-8") as log_f: log_f.write(f"UnknownError: {item.path} - {str(e)}\n") ...
2. 提前校验文件有效性
在解析前先做简单的JPEG头校验,过滤掉非标准或彻底损坏的文件:
def is_valid_jpeg(file_path): try: with open(file_path, "rb") as f: # JPEG标准文件头是FF D8 return f.read(2) == b'\xff\xd8' except: return False ... for item in your_items: full_path = f"{old_source_path}{item.path}" if not is_valid_jpeg(full_path): print(f"跳过非JPEG/损坏文件:{item.path}") with open("exif_error_log.txt", "a", encoding="utf-8") as log_f: log_f.write(f"InvalidJPEG: {item.path}\n") continue # 后续的EXIF修改逻辑 ...
3. 换用更健壮的EXIF处理库
如果Plum的异常频繁出现,直接换成熟度更高的库,比如piexif或exifread,这些库对异常文件的兼容性更好。
举个piexif的实现例子:
import piexif # 辅助函数:把十进制经纬度转成piexif要求的格式 def deg2dms(deg): d = int(deg) md = abs(deg - d) * 60 m = int(md) sd = (md - m) * 60 # 返回(度数,分母),(分数,分母),(秒数,分母)的格式 return ((d, 1), (m, 1), (int(sd * 10000), 10000)) ... for item in your_items: try: src_path = f"{old_source_path}{item.path}" dst_path = f"{new_target_path}{item.path}" # 加载EXIF数据 exif_dict = piexif.load(src_path) # 修改版权信息 exif_dict["0th"][piexif.ImageIFD.Copyright] = "Copyright 2023 somebody. All Rights Reserved." # 设置GPS信息 exif_dict["GPS"][piexif.GPSIFD.GPSLatitude] = deg2dms(item.latitude) exif_dict["GPS"][piexif.GPSIFD.GPSLatitudeRef] = "N" if item.latitude >= 0 else "S" exif_dict["GPS"][piexif.GPSIFD.GPSLongitude] = deg2dms(item.longitude) exif_dict["GPS"][piexif.GPSIFD.GPSLongitudeRef] = "E" if item.longitude >= 0 else "W" exif_dict["GPS"][piexif.GPSIFD.GPSAltitude] = (int(item.altitude * 100), 100) exif_dict["GPS"][piexif.GPSIFD.GPSAltitudeRef] = 0 if item.altitude >= 0 else 1 # 保存修改后的EXIF exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, src_path, dst_path) except Exception as e: print(f"文件 {item.path} 处理失败:{str(e)}") with open("exif_error_log.txt", "a", encoding="utf-8") as log_f: log_f.write(f"PiexifError: {item.path} - {str(e)}\n") ...
4. 先修复损坏的EXIF结构
对于部分只是EXIF结构损坏的文件,可以先用exiftool命令行工具批量修复,再用代码处理:
# 重置并重建EXIF数据,修复结构错误 exiftool -all= -tagsfromfile @ -all:all -unsafe -overwrite_original /path/to/your/images/*.jpg
内容的提问来源于stack exchange,提问作者ML Rozendale
相关产品推荐
相关产品推荐

