本文目录导读:

工具特点
- 自动读取EXIF:使用
Pillow库读取图片的拍摄时间。 - 日期格式化:默认格式为
YYYYMMDD_HHMMSS(20231005_143022.jpg)。 - 防重名处理:如果同一秒内有多张照片,会自动添加序号(如
_001)。 - 支持多种格式:
.jpg、.jpeg、.png、.tiff、.bmp、.webp等常见图片格式。 - 预览模式:先展示将要进行的修改,确认后再执行。
完整代码
import os
import sys
import re
from datetime import datetime
from PIL import Image
from PIL.ExifTags import TAGS
def get_date_from_exif(filepath):
"""尝试从EXIF中提取拍摄日期"""
try:
img = Image.open(filepath)
exif_data = img._getexif()
if exif_data:
for tag_id, value in exif_data.items():
tag_name = TAGS.get(tag_id, tag_id)
if tag_name == 'DateTimeOriginal':
# 格式: 'YYYY:MM:DD HH:MM:SS'
return datetime.strptime(value, '%Y:%m:%d %H:%M:%S')
return None
except Exception as e:
# 如果PIL无法读取或文件损坏
return None
def get_date_from_file_modification(filepath):
"""获取文件修改日期作为备用"""
mod_time = os.path.getmtime(filepath)
return datetime.fromtimestamp(mod_time)
def sanitize_filename(filename):
"""清理文件名中的非法字符"""
return re.sub(r'[<>:"/\\|?*]', '_', filename)
def batch_rename_images(folder_path, date_format='%Y%m%d_%H%M%S', preview=True, use_exif=True, use_mod_date_fallback=True):
"""
批量重命名图片文件,按日期命名。
Args:
folder_path (str): 图片所在的文件夹路径
date_format (str): 日期格式字符串,如 '%Y%m%d_%H%M%S'
preview (bool): 如果为True,只打印将要进行的修改,不实际执行
use_exif (bool): 是否优先使用EXIF日期
use_mod_date_fallback (bool): 如果EXIF无效,是否使用文件修改日期
"""
if not os.path.isdir(folder_path):
print(f"错误:路径 '{folder_path}' 不存在或不是目录。")
return
# 支持的图片扩展名(可自行添加)
image_extensions = {'.jpg', '.jpeg', '.png', '.tiff', '.tif', '.bmp', '.webp', '.gif'}
# 获取所有图片文件列表(非递归,仅当前目录)
files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]
image_files = [f for f in files if os.path.splitext(f)[1].lower() in image_extensions]
if not image_files:
print("未找到图片文件。")
return
print(f"找到 {len(image_files)} 个图片文件。")
print("-" * 50)
# 用于跟踪已使用的名称,防止重名
used_names = {}
rename_operations = []
for idx, filename in enumerate(image_files, start=1):
filepath = os.path.join(folder_path, filename)
ext = os.path.splitext(filename)[1].lower()
# 获取日期
date_taken = None
if use_exif:
date_taken = get_date_from_exif(filepath)
# 如果EXIF无效,使用修改日期
if date_taken is None and use_mod_date_fallback:
date_taken = get_date_from_file_modification(filepath)
if date_taken is None:
print(f"[跳过] {filename}: 无法获取日期信息")
continue
# 生成基础新名称
base_new_name = date_taken.strftime(date_format) + ext
base_new_name = sanitize_filename(base_new_name)
# 处理重名:如果同一时间有多张,加序号
new_name = base_new_name
counter = 1
while new_name in used_names or (not preview and os.path.exists(os.path.join(folder_path, new_name)) and new_name != filename):
new_name = f"{base_new_name[:-4]}_{counter:03d}{ext}"
counter += 1
used_names[new_name] = True
if filename == new_name:
# 如果新旧文件名相同,跳过(可能需要重命名?但文件名不变没必要)
print(f"[不变] {filename}")
continue
rename_operations.append((filename, new_name))
# 预览结果
print("\n预览 - 将要进行的重命名操作:")
print("-" * 50)
for old, new in rename_operations:
print(f" {old:40s} -> {new}")
if not rename_operations:
print("没有需要重命名的文件。")
return
if preview:
print(f"\n总共有 {len(rename_operations)} 个文件将被重命名。(预览模式,未实际执行)")
print("如需执行,请将 preview 参数设为 False。")
return
# 实际执行重命名
confirm = input(f"\n是否要执行这 {len(rename_operations)} 个重命名操作?(y/n): ").strip().lower()
if confirm != 'y':
print("已取消操作。")
return
print("\n正在执行重命名...")
for old, new in rename_operations:
old_path = os.path.join(folder_path, old)
new_path = os.path.join(folder_path, new)
try:
os.rename(old_path, new_path)
print(f" [完成] {old} -> {new}")
except Exception as e:
print(f" [错误] {old} -> {new}: {e}")
print("\n重命名完成!")
# ==================================
# 使用示例
# ==================================
if __name__ == "__main__":
# 请修改为您的图片文件夹路径
target_folder = "." # 当前目录
# 如果需要指定路径, target_folder = "D:/照片/2024旅行"
# 先以预览模式运行
batch_rename_images(
folder_path=target_folder,
date_format='%Y%m%d_%H%M%S', # 20231005_143022
preview=True, # 预览模式,不实际修改
use_exif=True, # 优先使用EXIF拍摄日期
use_mod_date_fallback=True # EXIF无效时使用文件修改日期
)
print("\n\n如果预览结果满意,请将 preview 改为 False 再运行一次以执行。")
使用方法
-
安装依赖:
pip install pillow
-
配置路径:
- 在代码末尾的
target_folder变量中填入您的图片文件夹路径。 - 或直接设为 表示当前目录。
- 在代码末尾的
-
运行:
python rename_images_by_date.py
-
预览与确认:
- 默认以 预览模式 运行,仅显示将要进行的修改,不会实际重命名。
- 预览满意后,将
preview=False并再次运行,程序会要求您输入y确认后执行。
自定义选项
| 参数 | 说明 | 示例 |
|---|---|---|
date_format |
日期格式 | '%Y%m%d_%H%M%S' → 20231005_143022 |
'%Y-%m-%d' → 2023-10-05 |
||
'%Y%m%d_%H%M%S' → 20231005_143022 |
||
preview |
预览模式 | True(只显示不执行) |
use_exif |
是否使用EXIF | True(推荐) |
use_mod_date_fallback |
是否使用修改日期作为后备 | True |
注意事项
- EXIF信息:只有数码相机、手机拍摄的照片通常含有EXIF日期,屏幕截图、网络下载的图片可能没有。
- 备份:建议先复制一份图片到测试文件夹,确认工具运行正常后再处理重要文件。
- 格式支持:GIF、WebP等格式可能不含EXIF信息,此时会使用修改日期。
如果您需要更复杂的功能(如递归子目录、自定义命名规则、添加前缀/后缀等),可以进一步扩展代码。
标签: 按日期
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。