【Python】批量重命名图片和 JSON 文件 - 完整代码

一、简单介绍

在使用标注软件进行标注时,会产生json文件,当我们需要批量重命名图片数据集名称时,对应的json文件并非简单修改文件命名即可,而是还需要修改每个json文件内容中“imagePath”对应的图片名称,才可以正常打开。

二、完整代码

注意:除了修改新旧文件夹路径和新文件名前缀外,也要将”dry_run = True“修改为”dry_run = False“才会进行重命名且输出对应文件的操作。

import os
import json
import shutil
from pathlib import Path

def batch_rename_and_update_json(
    # 源文件夹路径配置
    image_source_folder,  # 旧图片文件夹路径
    json_source_folder,   # 旧JSON文件夹路径
    
    # 目标文件夹路径配置
    image_target_folder,  # 新图片文件夹路径
    json_target_folder,   # 新JSON文件夹路径
    
    # 重命名配置(修改if __name__ == "__main__"后的配置,这里可不修改)
    prefix="img_",        # 新文件名前缀(如"img_"将生成img_0001.jpg)
    start_index=1,        # 序号起始值
    padding=4,            # 序号补零位数(4表示生成0001, 0002)
    sort_by="name",       # 文件排序方式:name=按文件名,mtime=按修改时间
    dry_run=False         # 试运行模式(只显示处理计划,不执行实际操作)
):
    """批量重命名图片和JSON文件,并更新JSON中的imagePath字段"""
    
    # 确保目标文件夹存在
    if not dry_run:
        os.makedirs(image_target_folder, exist_ok=True)
        os.makedirs(json_target_folder, exist_ok=True)
    
    # 获取所有图片文件
    image_files = []
    for filename in os.listdir(image_source_folder):
        full_path = os.path.join(image_source_folder, filename)
        if os.path.isfile(full_path) and filename.lower().endswith(('.jpg', '.jpeg', '.png')):
            image_files.append(filename)
    
    # 排序文件列表
    if sort_by == "mtime":
        image_files.sort(key=lambda x: os.path.getmtime(os.path.join(image_source_folder, x)))
    else:  # 默认按文件名排序
        image_files.sort()
    
    # 处理每个图片文件
    current_index = start_index
    processed_count = 0
    skipped_count = 0
    
    print("\n=== 开始处理 ===")
    for filename in image_files:
        # 获取图片文件信息
        image_name, image_ext = os.path.splitext(filename)
        
        # 构建对应的JSON文件路径
        json_filename = f"{image_name}.json"
        json_source_path = os.path.join(json_source_folder, json_filename)
        
        # 检查JSON文件是否存在
        if not os.path.exists(json_source_path):
            print(f"警告:未找到对应的JSON文件:{json_filename}")
            skipped_count += 1
            continue
        
        # 生成新的图片文件名(前缀+序号)
        new_image_name = f"{prefix}{str(current_index).zfill(padding)}{image_ext}"
        current_index += 1
        
        # 生成新的JSON文件名(保持与图片同名)
        new_json_name = os.path.splitext(new_image_name)[0] + ".json"
        
        # 构建目标路径
        image_target_path = os.path.join(image_target_folder, new_image_name)
        json_target_path = os.path.join(json_target_folder, new_json_name)
        
        # 打印处理计划
        print(f"[{filename}] → [{new_image_name}]")
        
        # 执行操作(非试运行模式)
        if not dry_run:
            try:
                # 复制并重命名图片文件
                shutil.copy2(os.path.join(image_source_folder, filename), image_target_path)
                
                # 更新并复制JSON文件
                with open(json_source_path, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                
                # 更新imagePath字段
                data["imagePath"] = new_image_name
                
                # 保存更新后的JSON
                with open(json_target_path, 'w', encoding='utf-8') as f:
                    json.dump(data, f, ensure_ascii=False, indent=2)
                
                processed_count += 1
            except Exception as e:
                print(f"错误:处理文件 {filename} 时出错: {str(e)}")
                skipped_count += 1
    
    # 输出统计信息
    print("\n=== 处理完成 ===")
    print(f"总共处理: {processed_count} 个文件")
    print(f"跳过: {skipped_count} 个文件")
    
    if dry_run:
        print("\n注意:本次为试运行模式,未执行实际操作。")
    else:
        print(f"图片保存到: {image_target_folder}")
        print(f"JSON保存到: {json_target_folder}")

if __name__ == "__main__":
    # =========================================
    # 配置参数(请根据需要修改以下值)
    # =========================================
    
    # 源文件夹路径配置(支持绝对路径和相对路径)
    image_source_folder = "D:/old_images"     # 旧图片文件夹路径
    json_source_folder = "D:/old_jsons"       # 旧JSON文件夹路径
    
    # 目标文件夹路径配置(处理后的文件将保存到这里)
    image_target_folder = "D:/new_images"     # 新图片文件夹路径
    json_target_folder = "D:/new_jsons"       # 新JSON文件夹路径
    
    # 重命名配置
    prefix = "product_"                       # 新文件名前缀(如"product_"将生成product_0001.jpg)
    start_index = 1                           # 序号起始值
    padding = 4                               # 序号补零位数(4表示生成0001, 0002)
    sort_by = "name"                          # 文件排序方式:name=按文件名,mtime=按修改时间
    dry_run = True                            # 是否试运行(True=只预览,False=执行实际操作)
    
    # =========================================
    # 执行批量处理(无需修改以下代码)
    # =========================================
    
    # 确保路径正确
    image_source_folder = str(Path(image_source_folder))
    json_source_folder = str(Path(json_source_folder))
    image_target_folder = str(Path(image_target_folder))
    json_target_folder = str(Path(json_target_folder))
    
    # 打印配置信息
    print("\n=== 配置信息 ===")
    print(f"图片源文件夹: {image_source_folder}")
    print(f"JSON源文件夹: {json_source_folder}")
    print(f"图片目标文件夹: {image_target_folder}")
    print(f"JSON目标文件夹: {json_target_folder}")
    print(f"重命名格式: {prefix}[序号].jpg (序号从{start_index}开始,补零到{padding}位)")
    print(f"文件排序方式: {sort_by}")
    print(f"试运行模式: {'是' if dry_run else '否'}")
    
    # 执行批量处理
    batch_rename_and_update_json(
        image_source_folder, json_source_folder,
        image_target_folder, json_target_folder,
        prefix, start_index, padding, sort_by, dry_run
    )

主要功能是将一组图片和对应的 JSON 文件按照指定规则重命名,并更新 JSON 文件中的图片路径引用。

三、核心功能

  • 批量重命名图片文件(如 JPG、PNG)和对应的 JSON 文件
  • 自动更新 JSON 文件中的imagePath字段,确保引用的是新文件名
  • 支持按文件名或修改时间排序文件
  • 提供试运行模式,可预览操作结果而不实际执行
  • 生成结构化的处理报告,显示成功和失败的文件数量

四、参数配置

  • 路径配置:指定源图片、源 JSON 文件夹路径,以及目标保存位置
  • 命名规则:可自定义前缀、起始序号和补零位数(如product_0001.jpg
  • 排序方式:支持按文件名 (name) 或修改时间 (mtime) 排序
  • 试运行模式:通过dry_run=True预览操作,避免意外修改

五、执行流程

检查并创建目标文件夹

读取并排序源图片文件

为每个图片生成对应的新文件名

查找匹配的 JSON 文件并更新其中的imagePath字段

复制并重命名图片和 JSON 文件到目标位置

输出处理统计信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扶云云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值