You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改图片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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 01:32:49