我的知识记录

Python批量重命名图片按拍摄时间教程

用Python读取照片EXIF拍摄时间信息,批量重命名为YYYYMMDD_HHMMSS格式,手机照片导入电脑后按时间排序整理神器。

场景痛点

从手机导出一堆照片,文件名全是 IMG_20250101_123456 这种系统自动命名,混着微信保存的图片、截图,想按拍摄时间排个序,手动改文件名能改到眼花。用Python读取每张照片的EXIF拍摄时间,自动重命名成 20250101_123456_北京会议.jpg 这种格式,一眼看出什么时候拍的。

用到的库

pip install Pillow

读取图片EXIF用 Pillow(PIL的现代分支),重命名用标准库 os

完整代码

import os
from pathlib import Path
from datetime import datetime
from PIL import Image
from PIL.ExifTags import TAGS


IMAGE_EXTS = {".jpg", ".jpeg", ".png", ".heic", ".tiff", ".bmp"}


def get_shoot_time(img_path: Path):
"""从图片EXIF里读取拍摄时间,读不到就返回文件修改时间。"""
try:
with Image.open(img_path) as img:
exif = img._getexif()
if not exif:
return None
# 遍历EXIF字段,找 DateTimeOriginal(拍摄时间)
for tag_id, value in exif.items():
tag = TAGS.get(tag_id, tag_id)
if tag == "DateTimeOriginal":
# EXIF时间格式:"2025:01:15 14:30:25"
return datetime.strptime(value, "%Y:%m:%d %H:%M:%S")
except Exception:
return None
return None


def rename_by_shoot_time(img_dir: str, prefix: str = ""):
"""批量把目录里的图片按拍摄时间重命名。"""
root = Path(img_dir)
renamed = []
skipped = []

for p in root.iterdir():
if p.suffix.lower() not in IMAGE_EXTS:
continue
if not p.is_file():
continue

shoot_dt = get_shoot_time(p)
if shoot_dt is None:
# 读不到EXIF就用文件修改时间兜底
shoot_dt = datetime.fromtimestamp(p.stat().st_mtime)
note = "(用修改时间兜底)"
else:
note = ""

# 新文件名格式:前缀_年月日_时分秒.后缀
new_name = shoot_dt.strftime("%Y%m%d_%H%M%S")
if prefix:
new_name = f"{prefix}_{new_name}"
new_path = root / f"{new_name}{p.suffix.lower()}"

# 重名加序号
i = 1
while new_path.exists() and new_path != p:
new_path = root / f"{new_name}_{i}{p.suffix.lower()}"
i += 1

try:
p.rename(new_path)
renamed.append((p.name, new_path.name, note))
print(f"{p.name} -> {new_path.name} {note}")
except OSError as e:
skipped.append((p.name, str(e)))

return renamed, skipped


if __name__ == "__main__":
IMG_DIR = r"D:\照片\2025年会"
PREFIX = "年会"  # 文件名前缀,不需要就传空字符串

renamed, skipped = rename_by_shoot_time(IMG_DIR, PREFIX)
print(f"\n成功重命名 {len(renamed)} 张,跳过 {len(skipped)} 张")
if skipped:
print("失败明细:")
for name, err in skipped:
print(f"  {name}: {err}")

代码讲解

Image.open 打开图片后,_getexif() 返回EXIF信息字典,键是数字ID,值是内容。用 PIL.ExifTags.TAGS 把数字ID转成可读名称,找 DateTimeOriginal 字段——这就是相机/手机记录的实际拍摄时间。EXIF时间格式比较特殊,是 2025:01:15 14:30:25(月日之间是冒号不是横杠),用 strptime 按这个格式解析。读不到EXIF的图片(比如截图、网络保存的图),用文件修改时间兜底,保证所有图片都能被重命名。新文件名用 strftime("%Y%m%d_%H%M%S") 生成,同秒多张加序号,不会覆盖。

运行结果

控制台逐行打印原名和新名对照,带"(用修改时间兜底)"标记的是没有EXIF信息的图片。运行完目录里所有图片都变成 年会_20250115_143025.jpg 这种格式,按文件名排序就是按拍摄时间排序。

注意事项

  • PNG截图一般没有EXIF拍摄时间字段,会自动走修改时间兜底。
  • HEIC格式(iPhone默认)Pillow默认不支持,需要额外装 pillow-heif 库。
  • 重命名前建议先备份原图,脚本虽然有重名保护,但误操作不好回退。
  • 同一张连拍照片可能拍摄时间完全相同,脚本自动加序号 _1_2

Python批量重命名图片按拍摄时间教程

标签:

更新时间:2026-09-14 21:26:18

上一篇:Python 按序号批量重命名文件:照片报表编号实战

下一篇:Python 批量重命名文件教程:os.rename 实战详解