Python批量重命名照片:基于EXIF时间戳的自动化整理方案

Python批量重命名照片:基于EXIF时间戳的自动化整理方案 1. 项目背景与需求解析每次旅行或重要活动后手机相册里总会堆积大量照片。这些照片默认以IMG_20230101_123456.jpg这类无意义的随机字符串命名给后期整理带来极大困扰。更糟的是当从不同设备导入照片时文件名可能重复导致覆盖造成珍贵影像永久丢失。照片的EXIF元数据中其实隐藏着精确的拍摄时间戳精确到秒这正是我们需要的天然排序依据。通过读取这些信息并批量重命名可以实现按时间线自动整理照片避免文件名冲突快速定位特定时间点的照片为照片管理软件提供结构化数据2. 技术实现方案选型2.1 EXIF信息提取照片的EXIF(Exchangeable Image File Format)数据存储在文件头部包含拍摄时间、相机型号、GPS位置等信息。关键时间标签包括DateTimeOriginal原始拍摄时间CreateDate创建日期ModifyDate修改日期优先使用DateTimeOriginal若不存在则回退到CreateDate。需注意不同相机厂商的标签差异。2.2 开发语言选择Python是最佳选择因为成熟的EXIF处理库Pillow、ExifRead原生文件系统操作支持跨平台兼容性简单的多线程实现2.3 重命名策略设计推荐的时间戳格式YYYY-MM-DD_HH-MM-SS 示例2023-07-15_14-30-05.jpg遇到时间冲突时同一秒多张照片自动追加序号 2023-07-15_14-30-05(1).jpg 2023-07-15_14-30-05(2).jpg3. 完整实现代码解析import os from PIL import Image from PIL.ExifTags import TAGS import datetime def get_exif_time(image_path): try: img Image.open(image_path) exif img._getexif() if exif: for tag_id, value in exif.items(): tag_name TAGS.get(tag_id, tag_id) if tag_name DateTimeOriginal: return datetime.datetime.strptime(value, %Y:%m:%d %H:%M:%S) # 获取文件创建时间作为备选 return datetime.datetime.fromtimestamp(os.path.getmtime(image_path)) except Exception as e: print(fError reading {image_path}: {str(e)}) return None def batch_rename(folder_path): time_dict {} for filename in os.listdir(folder_path): if filename.lower().endswith((.jpg, .jpeg, .png)): filepath os.path.join(folder_path, filename) photo_time get_exif_time(filepath) if photo_time: time_str photo_time.strftime(%Y-%m-%d_%H-%M-%S) # 处理时间冲突 if time_str in time_dict: time_dict[time_str] 1 new_name f{time_str}({time_dict[time_str]}).jpg else: time_dict[time_str] 0 new_name f{time_str}.jpg new_path os.path.join(folder_path, new_name) os.rename(filepath, new_path) print(fRenamed: {filename} - {new_name}) if __name__ __main__: target_folder input(Enter folder path: ) batch_rename(target_folder)4. 高级功能扩展4.1 保留原始文件信息建议在重命名时保留部分原文件名中的关键信息如相机型号# 在get_exif_time函数中添加 model exif.get(TAGS.get(306)) # 306对应Camera Model Name if model: return f{time_str}_{model.replace( ,)}.jpg4.2 多线程处理对于大量照片1000使用线程池加速from concurrent.futures import ThreadPoolExecutor def process_file(filename): # 处理逻辑... with ThreadPoolExecutor(max_workers8) as executor: executor.map(process_file, os.listdir(folder_path))4.3 日志记录记录重命名映射关系方便回滚import csv with open(rename_log.csv, a) as f: writer csv.writer(f) writer.writerow([original_name, new_name, datetime.now()])5. 常见问题解决方案5.1 EXIF数据缺失可能原因及对策截图或编辑后丢失 - 使用文件修改时间网络下载图片 - 尝试读取HTTP头中的Last-Modified格式不支持 - 跳过或使用文件名中的时间信息5.2 文件名冲突处理推荐三种冲突解决策略追加序号默认哈希值后缀确保唯一性保留部分原文件名平衡可读性与唯一性5.3 特殊字符处理Windows系统文件名不能包含: \ / : * ? | 需在时间格式中用-替代:time_str photo_time.strftime(%Y-%m-%d_%H-%M-%S) # 而非%H:%M:%S6. 实际应用建议预处理检查先运行扫描模式输出重命名预览而不实际修改文件分批处理超过5000张照片时按日期子文件夹分批处理备份策略建议先复制到新目录处理而非直接修改原文件扩展命名可加入地点信息通过EXIF GPS数据解析关键安全提示处理他人照片前务必清除敏感EXIF信息GPS定位、设备序列号等可使用exiftool -all *.jpg批量清除我实际处理过3万多张家庭照片的经验是先按年份建立文件夹结构再在每个年份文件夹内执行时间重命名。配合Lightroom等管理软件能建立完美的时光轴系统。对于老照片扫描件可以手动补充拍摄时间到EXIF信息后再处理。