news 2026/9/3 1:05:37

Python批量处理图片:重命名、压缩与归档完整方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python批量处理图片:重命名、压缩与归档完整方案

看到你正在整理“暗影花仙精灵王”系列的卡牌图片,这种图片素材通常数量多、文件名混乱、格式不统一,手动一张张重命名和压缩非常低效。结合我过去的批量图片处理经验,整理了一套完整的 Python 批量处理方案,可以把图片整理这件事彻底自动化。

本文会从实际需求出发,带你用 Python 实现“暗影花仙精灵王卡牌图片(3)”这类批次图片的批量重命名、统一压缩、格式转换和统计归档,全程提供可直接复制的代码。

1. 背景与核心概念

1.1 什么是图片批量处理

图片批量处理是指通过脚本或工具,一次性对大量图片文件执行相同或相似的操作。常见的操作包括:

  • 批量重命名,将“IMG_20250401_123456.jpg”这种相机默认名改成“暗影花仙精灵王_003.jpg”这种有语义的名字。
  • 批量压缩,将高分辨率图片等比缩小,降低存储占用。
  • 批量转换格式,比如把 PNG 转为 JPG,或者统一输出为 WebP。
  • 批量统计,统计每个批次图片的数量、尺寸分布、总大小。
  • 重复检测,找出内容完全相同或接近的图片。

在这个需求里,“(3)”通常代表第 3 个批次,也就是一批编号连续的卡牌图片素材。我们需要把这一批图片按一定规则归整好。

1.2 为什么用 Python

Python 在图片处理领域有非常成熟的生态,尤其是 Pillow 库,几乎是图像处理的标准库。使用 Python 处理图片有以下优势:

优势说明
语法简单处理逻辑清晰,适合维护和调整
跨平台Windows、Linux、macOS 都能跑同一套脚本
生态丰富配合 pathlib、re、argparse 等标准库,无需额外安装太多依赖
数据处理方便可以配合 pandas 生成图片清单 Excel
可扩展性强后续要接入 OCR、AI 分类也方便

1.3 适用场景

  • 游戏卡牌图片整理,例如“暗影花仙精灵王”系列各批次卡图。
  • 电商商品图批量压缩。
  • 摄影素材按日期和主题归档。
  • 设计师交付图统一命名。
  • 训练数据集的预处理。

2. 环境准备与版本说明

本文以常见环境为例,具体版本请根据你的实际情况调整。建议使用 Python 3.8 及以上版本,Pillow 使用 8.0 以上版本。

2.1 验证 Python 环境

在命令行执行:

python --version

如果你看到类似Python 3.10.12的输出,说明环境正常。如果提示找不到命令,可以尝试python3

2.2 安装 Pillow

Pillow 是 Python 中最常用的图像处理库,它是 PIL(Python Imaging Library)的积极维护分支。

pip install pillow

国内网络环境下可以使用国内镜像加速:

pip install pillow -i https://pypi.tuna.tsinghua.edu.cn/simple

安装完成后验证:

python -c "from PIL import Image; print(Image.__version__)"

能看到版本号就说明 Pillow 安装成功。

2.3 示例目录结构

假设我们拿到了一批图片素材,目录结构如下:

cards_batch3/ ├── raw/ # 原始图片 │ ├── 01.jpg │ ├── 02.png │ ├── 03.jpg │ └── ... ├── output/ # 处理后的图片 └── logs/ # 运行日志

我们把原始图片放在raw目录,处理结果输出到output目录,日志放在logs目录。这样结构清晰,后续扩展也方便。

3. 核心知识点拆解

3.1 Pillow 的基本使用

Pillow 可以打开各种格式的图片,并能获取图片的基本信息:

from PIL import Image img = Image.open("raw/01.jpg") print(img.size) print(img.mode) print(img.format)
  • size:一个元组,例如(1920, 1080),表示宽和高。
  • mode:像素模式,常见的有RGBRGBAL(灰度)。
  • format:原始文件格式,例如JPEGPNG

这是批量处理的基础,因为后续的压缩、转换都需要先打开图片。

3.2 pathlib 路径管理

Python 标准库pathlib提供了面向对象的路径操作,写起来比os.path更简洁:

from pathlib import Path input_dir = Path("raw") output_dir = Path("output") # 遍历目录下所有图片文件 for img_path in input_dir.glob("*.jpg"): print(img_path.name)
  • Path("raw")创建路径对象。
  • .glob("*.jpg")匹配目录下所有.jpg文件。
  • .name获取文件名。
  • .stem获取不带后缀的文件名。
  • .suffix获取文件后缀。

3.3 批量重命名规则设计

在开始写代码之前,先明确重命名规则。本文采用:

暗影花仙精灵王_001.jpg 暗影花仙精灵王_002.jpg 暗影花仙精灵王_003.jpg

规则说明:

  • 前缀固定为“暗影花仙精灵王”,中间用下划线分隔。
  • 序号使用 3 位数字,不足补 0,方便排序。
  • 原文件后缀保留,但如果图片实际格式与后缀不一致,应统一纠正。

之所以用 3 位数字,是考虑到同一批图片数量通常不超过 999 张。如果批次数量更大,可以改成04d即 4 位数字。

3.4 图片压缩与转换原理

卡牌图片一般是高清大图,动辄几 MB。为了便于分享和传输,通常需要压缩。压缩的核心参数有两个:

  • 尺寸:等比缩小宽度和高度。
  • 质量:JPG 格式有 1-100 的质量参数,值越大文件越大,画质也越好。

Pillow 中调整尺寸使用resize方法,保存 JPG 时指定quality参数:

img.thumbnail((800, 800)) img.save("output/compressed.jpg", quality=85)

thumbnail会保持图片比例,且不会放大图片。这个特性非常适合批量压缩。

4. 完整实战案例

下面进入核心部分。我们将编写三个脚本:

  1. rename_images.py:批量重命名图片。
  2. compress_images.py:批量压缩图片。
  3. generate_manifest.py:生成图片信息清单。

建议把这些脚本放在项目根目录下的scripts目录。

4.1 创建项目结构

首先创建以下目录结构:

cards_batch3/ ├── raw/ ├── output/ ├── logs/ └── scripts/

在命令行中执行:

mkdir -p cards_batch3/{raw,output,logs,scripts}

如果你用的是 Windows PowerShell,可以分开执行:

mkdir cards_batch3\raw mkdir cards_batch3\output mkdir cards_batch3\logs mkdir cards_batch3\scripts

4.2 编写批量重命名脚本

文件路径:cards_batch3/scripts/rename_images.py

# -*- coding: utf-8 -*- """ 卡牌图片批量重命名脚本 规则:暗影花仙精灵王_001.jpg """ import re from pathlib import Path # 配置 INPUT_DIR = Path(__file__).parent.parent / "raw" PREFIX = "暗影花仙精灵王" START_INDEX = 1 DIGIT_COUNT = 3 # 支持处理的图片格式 SUPPORTED_SUFFIXES = {".jpg", ".jpeg", ".png", ".webp", ".bmp"} def main(): # 检查目录是否存在 if not INPUT_DIR.exists(): print(f"错误:目录不存在 {INPUT_DIR}") return # 获取所有图片文件,按文件名排序 image_files = [ p for p in INPUT_DIR.iterdir() if p.is_file() and p.suffix.lower() in SUPPORTED_SUFFIXES ] image_files.sort(key=lambda p: p.name) if not image_files: print("错误:没有找到任何图片文件") return print(f"发现 {len(image_files)} 张图片,开始重命名...") # 记录重命名结果 rename_records = [] index = START_INDEX for img_path in image_files: # 构造新文件名 new_name = f"{PREFIX}_{index:0{DIGIT_COUNT}d}{img_path.suffix.lower()}" new_path = img_path.with_name(new_name) # 如果目标文件名已存在且不是同一个文件,则跳过 if new_path.exists() and new_path != img_path: print(f"跳过 {img_path.name} -> {new_name},目标文件已存在") continue # 执行重命名 img_path.rename(new_path) rename_records.append((img_path.name, new_name)) print(f"重命名:{img_path.name} -> {new_name}") index += 1 # 写入日志 log_dir = Path(__file__).parent.parent / "logs" log_dir.mkdir(exist_ok=True) log_file = log_dir / "rename_log.txt" with open(log_file, "w", encoding="utf-8") as f: for old_name, new_name in rename_records: f.write(f"{old_name}\t{new_name}\n") print(f"重命名完成,共处理 {len(rename_records)} 张图片") print(f"日志已保存:{log_file}") if __name__ == "__main__": main()

脚本说明:

  • INPUT_DIR使用了Path(__file__).parent.parent / "raw",意思是“当前脚本文件所在目录的上一级目录下的 raw 目录”,这样不管从哪个目录执行脚本都能正确定位。
  • SUPPORTED_SUFFIXES限制了处理的文件类型,避免误处理非图片文件。
  • 重命名前检查目标文件是否已存在,避免覆盖已有文件。
  • 日志以旧文件名 + Tab + 新文件名的格式存入logs/rename_log.txt,方便审计和回滚。

运行脚本:

cd cards_batch3 python scripts/rename_images.py

4.3 编写批量压缩脚本

文件路径:cards_batch3/scripts/compress_images.py

# -*- coding: utf-8 -*- """ 卡牌图片批量压缩脚本 功能:等比缩放图片,压缩 JPG 质量,将 PNG 转为 JPG 输出 """ from pathlib import Path from PIL import Image # 配置 RAW_DIR = Path(__file__).parent.parent / "raw" OUTPUT_DIR = Path(__file__).parent.parent / "output" MAX_WIDTH = 800 # 目标最大宽度 MAX_HEIGHT = 800 # 目标最大高度 JPG_QUALITY = 85 # JPG 压缩质量,范围 1-100 OUTPUT_FORMAT = "JPEG" # 输出格式:JPEG / PNG / WEBP def process_image(img_path: Path, output_path: Path) -> tuple: """ 处理单张图片,返回 (原文件名, 新文件名, 原大小, 新大小, 原尺寸, 新尺寸) """ with Image.open(img_path) as img: # 原始尺寸 original_size = img.size original_bytes = img_path.stat().st_size # 如果是 RGBA 模式,转为 RGB(JPG 不支持透明通道) if img.mode in ("RGBA", "P", "LA"): img = img.convert("RGB") # 等比缩放 img.thumbnail((MAX_WIDTH, MAX_HEIGHT)) # 新尺寸 new_size = img.size # 保存输出文件 output_path.parent.mkdir(parents=True, exist_ok=True) img.save(output_path, format=OUTPUT_FORMAT, quality=JPG_QUALITY) new_bytes = output_path.stat().st_size return ( img_path.name, output_path.name, original_bytes, new_bytes, original_size, new_size, ) def main(): if not RAW_DIR.exists(): print(f"错误:目录不存在 {RAW_DIR}") return supported_suffixes = {".jpg", ".jpeg", ".png", ".webp", ".bmp"} image_files = [ p for p in RAW_DIR.iterdir() if p.is_file() and p.suffix.lower() in supported_suffixes ] image_files.sort(key=lambda p: p.name) if not image_files: print("错误:没有找到任何图片文件") return # 输出目录 OUTPUT_DIR.mkdir(parents=True, exist_ok=True) print(f"发现 {len(image_files)} 张图片,开始压缩...") results = [] for img_path in image_files: # 新文件名:保持原名,后缀改为输出格式对应后缀 if OUTPUT_FORMAT == "JPEG": new_suffix = ".jpg" elif OUTPUT_FORMAT == "WEBP": new_suffix = ".webp" else: new_suffix = img_path.suffix.lower() new_name = img_path.stem + new_suffix output_path = OUTPUT_DIR / new_name try: result = process_image(img_path, output_path) results.append(result) old_kb = result[2] / 1024 new_kb = result[3] / 1024 ratio = new_kb / old_kb * 100 if old_kb > 0 else 0 print( f"压缩:{result[0]} -> {result[1]} | " f"{old_kb:.1f}KB -> {new_kb:.1f}KB | {ratio:.1f}%" ) except Exception as e: print(f"处理失败:{img_path.name},错误:{e}") # 生成统计日志 log_dir = Path(__file__).parent.parent / "logs" log_dir.mkdir(exist_ok=True) log_file = log_dir / "compress_log.txt" with open(log_file, "w", encoding="utf-8") as f: f.write("原文件名\t新文件名\t原大小(B)\t新大小(B)\t原尺寸\t新尺寸\n") for r in results: f.write(f"{r[0]}\t{r[1]}\t{r[2]}\t{r[3]}\t{r[4]}\t{r[5]}\n") total_old = sum(r[2] for r in results) total_new = sum(r[3] for r in results) total_ratio = total_new / total_old * 100 if total_old > 0 else 0 print(f"压缩完成,共处理 {len(results)} 张图片") print(f"总大小:{total_old / 1024 / 1024:.2f}MB -> {total_new / 1024 / 1024:.2f}MB") print(f"压缩率:{total_ratio:.1f}%") if __name__ == "__main__": main()

脚本说明:

  • Image.open之后,使用with上下文管理器,确保文件句柄被正确关闭。
  • img.thumbnail((MAX_WIDTH, MAX_HEIGHT))会按比例缩小图片,同时保证不超过设定的宽高。
  • quality=85是 JPG 保存时的质量参数。对于卡牌图片,85 是一个在画质和大小之间比较均衡的取值。
  • 日志记录了每张图片压缩前后的体积和尺寸变化,方便查看压缩效果。

运行脚本:

cd cards_batch3 python scripts/compress_images.py

4.4 编写图片信息清单生成脚本

文件路径:cards_batch3/scripts/generate_manifest.py

# -*- coding: utf-8 -*- """ 生成图片信息清单 输出:图片文件名、尺寸、大小、格式等信息的 CSV 文件 """ import csv from pathlib import Path from PIL import Image # 配置:处理 output 目录 TARGET_DIR = Path(__file__).parent.parent / "output" OUTPUT_CSV = Path(__file__).parent.parent / "logs" / "manifest.csv" def main(): if not TARGET_DIR.exists(): print(f"错误:目录不存在 {TARGET_DIR}") return supported_suffixes = {".jpg", ".jpeg", ".png", ".webp", ".bmp"} image_files = [ p for p in TARGET_DIR.iterdir() if p.is_file() and p.suffix.lower() in supported_suffixes ] image_files.sort(key=lambda p: p.name) if not image_files: print("错误:没有找到任何图片文件") return print(f"发现 {len(image_files)} 张图片,正在生成清单...") rows = [] for img_path in image_files: with Image.open(img_path) as img: size = img.size img_format = img.format file_size = img_path.stat().st_size rows.append({ "文件名": img_path.name, "格式": img_format, "宽度": size[0], "高度": size[1], "文件大小(B)": file_size, }) # 输出 CSV log_dir = OUTPUT_CSV.parent log_dir.mkdir(exist_ok=True) with open(OUTPUT_CSV, "w", encoding="utf-8-sig", newline="") as f: fieldnames = ["文件名", "格式", "宽度", "高度", "文件大小(B)"] writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() writer.writerows(rows) print(f"清单已生成:{OUTPUT_CSV}") print(f"共 {len(rows)} 张图片") if __name__ == "__main__": main()

脚本说明:

  • 这里使用utf-8-sig编码保存 CSV,这样用 Excel 直接打开不会出现中文乱码。
  • newline=""避免了 CSV 中每行后面多一个空行的问题。
  • 信息清单方便你核对整个批次的图片情况,也可以作为交付说明文档。

运行脚本:

cd cards_batch3 python scripts/generate_manifest.py

4.5 运行结果说明

按顺序执行三个脚本后,目录结构会变成:

cards_batch3/ ├── raw/ │ ├── 暗影花仙精灵王_001.jpg │ ├── 暗影花仙精灵王_002.jpg │ ├── 暗影花仙精灵王_003.jpg │ └── ... ├── output/ │ ├── 暗影花仙精灵王_001.jpg │ ├── 暗影花仙精灵王_002.jpg │ └── ... ├── logs/ │ ├── rename_log.txt │ ├── compress_log.txt │ └── manifest.csv └── scripts/ ├── rename_images.py ├── compress_images.py └── generate_manifest.py

raw目录下是重命名后的原始图片,output目录下是压缩后的图片,logs目录下是三个脚本生成的日志和清单文件。

5. 常见问题与排查思路

5.1 重命名时报错“目标文件已存在”

问题现象常见原因解决思路
重命名时提示目标文件已存在之前可能运行过脚本,部分文件已被重命名检查目标文件名对应的日志,确认之前是否处理过;删除多余文件或调整起始序号

如果重复运行重命名脚本,第二次运行时会发现暗影花仙精灵王_001.jpg已经存在,脚本会跳过。这是设计好的保护逻辑,防止覆盖已有文件。

5.2 压缩后图片大小反而变大

问题现象常见原因解决思路
压缩后文件比原图还大原图本身已经是高压缩比的 JPG 或尺寸不大;PNG 转 JPG 后质量参数偏高quality从 85 降到 70 重新压缩;或者只在原始图片尺寸较大时才压缩;可以将process_image中增加条件判断,如果新文件大于旧文件,则保留原文件

这里需要理解一个概念:JPG 是有损压缩,如果原始图片已经是质量很高的 JPG,再用quality=85重新压缩,生成的图片可能比原图还大。在实际处理中,可以把quality调低,或者增加“只压缩比原图小的图片”的逻辑。

5.3 PNG 图片压缩后透明背景变黑

问题现象常见原因解决思路
PNG 转 JPG 后,原本透明的区域变成黑色JPG 格式不支持透明通道,转换时透明像素被填充为黑色在转换前使用convert("RGB"),并将透明区域填充为白色,详见下方代码

如果卡牌图片有透明背景,转成 JPG 时建议先填充白色背景:

from PIL import Image img = Image.open("raw/带有透明背景的图片.png") if img.mode == "RGBA": background = Image.new("RGB", img.size, (255, 255, 255)) background.paste(img, mask=img.split()[-1]) img = background

这是在批量压缩脚本中值得补充的细节。如果你的卡牌图片不涉及透明背景,可以不处理。

5.4 脚本运行报错“ModuleNotFoundError: No module named 'PIL'”

这个错误说明 Pillow 没有安装成功。按顺序排查:

pip --version pip install pillow python -c "from PIL import Image; print('OK')"

如果 install 提示权限问题,可以在 Windows 上尝试:

pip install pillow --user

5.5 缩略图没有生效

thumbnail方法有一个特点:如果图片尺寸本身小于指定尺寸,它不会放大图片。也就是说,一张400x300的图片,即使设置MAX_WIDTH=800,也不会被放大到800x600

这通常是合理的行为。如果你希望统一尺寸,需要用resize并明确指定目标尺寸,但这样会改变图片宽高比,可能导致卡牌变形。建议优先使用thumbnail

6. 最佳实践与工程建议

6.1 操作前先做备份

图片处理是不可逆操作。虽然本文脚本的日志会记录原始文件名和新文件名的对应关系,但更稳妥的做法是在处理前对整个raw目录做一次备份:

cp -r raw raw_backup

Windows PowerShell:

Copy-Item -Path raw -Destination raw_backup -Recurse

有了备份,即使处理结果不理想,也能随时恢复。

6.2 使用 dry-run 模式

在正式执行重命名之前,可以加一个--dry-run参数,只打印操作结果而不真正执行。这样可以在实际操作前发现潜在问题。

下面是一个简化版的改造思路:

import sys DRY_RUN = "--dry-run" in sys.argv # 在重命名循环中 if DRY_RUN: print(f"[预演] {img_path.name} -> {new_name}") else: img_path.rename(new_path)

6.3 文件名编码问题

如果图片文件名包含中文或者特殊字符,在不同操作系统间传输时可能会出问题。建议:

  • 文件名统一使用中文字段加英文数字的组合,例如“暗影花仙精灵王_001”。
  • 避免在文件名中使用空格、/\:*?"<>|等特殊字符。

6.4 版权合规提醒

卡牌图片通常有版权归属。整理和处理这些图片时,应当注意:

  • 仅用于个人学习、素材管理和内部使用。
  • 不要未经授权公开传播无版权的素材图片。
  • 如果图片用于公开发布或商业用途,请先确认版权授权情况。

6.5 合理设置压缩质量

压缩质量并不是越低越好。对于卡牌类图片,建议:

用途质量参数说明
网络预览70-75文件小,加载快,肉眼基本无差别
本地归档82-88画质接近原图,体积控制较好
精修原图92-100保留细节,但文件较大

6.6 日志与审计

生产环境或重要项目里,批量处理一定要有日志。本文的日志采用文件名加Tab加结果的格式,便于后续用脚本或 Excel 分析。你也可以把日志接入统一的日志系统,便于追溯。

7. 总结与进一步扩展

通过这篇文章,你已经掌握了用 Python 对“暗影花仙精灵王卡牌图片(3)”这类批次图片进行完整整理的方法:

  1. rename_images.py批量重命名图片,规则清晰、日志可追溯。
  2. compress_images.py将图片等比压缩,控制文件大小。
  3. generate_manifest.py生成图片清单,方便核对和交付。

这三个脚本组成了一个完整的图片批处理工具链,后续可以按需扩展:

  • 加入图片去重功能,使用图像哈希算法检测重复图片。
  • 加入 OCR 识别,自动识别卡牌名称并作为文件名。
  • 加入水印功能,批量给图片添加版权水印。
  • 接入 Excel 报表,生成更美观的图片清单。

图片整理是一个基础且高频的需求,掌握这套脚本的思路后,不管是卡牌图片、摄影素材还是商品图,都能套用。建议你先拿少量图片测试,确认运行结果符合预期后再处理大批量数据。

如果本文对你有帮助,可以收藏备用。后续遇到图片处理相关问题,也欢迎在评论区交流讨论。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 1:04:02

Code as Worlds:智能体用可执行代码构建世界模型

在 Agent 研究和工程实践中&#xff0c;一个正在快速升温的方向是 “Code as Worlds”&#xff1a;智能体不再把对环境的理解只保存在自然语言描述或网络参数里&#xff0c;而是把环境规则写成一段可执行代码。也就是说&#xff0c;Agent 用 Python 函数表示自己学到的东西&…

作者头像 李华
网站建设 2026/9/3 0:56:13

为了更好地理解tidyr包的实际应用,我们来看看一个真实案例

下面的内容摘录自《用R探索医药数据科学》专栏文章的部分内容&#xff08;原文6047字&#xff09;。 2篇2章3节&#xff1a;处理医学类原始数据的重要技巧&#xff0c;R语言中的宽长数据转换&#xff0c;tidyr包的使用指南_r语言 医学公共数据库 变量类型及转换-CSDN博客 在数…

作者头像 李华
网站建设 2026/9/3 0:42:56

四足机器狗室外建图:Mid360与LIO-SAM调试全攻略

用 Mid360 跑 LIO-SAM 给四足机器狗做室外建图&#xff0c;最近问的人很多。这个组合最容易被误解的地方&#xff0c;是大家以为装上驱动、把 LIO-SAM 跑起来&#xff0c;就能复刻网上那种漂亮的彩色点云图。实际上从雷达上电、IP 配置、驱动版本、坐标外参&#xff0c;到机器狗…

作者头像 李华
网站建设 2026/9/3 0:35:04

墨见首发:基于OpenClaw引擎,你的全栈“赛博合伙人”已上线

如今, 在软件开发领域里, AI技术的应用正从技术验证阶段迈向更具实际意义的工程落地进程。与此同时, 开发者对于那些仅仅能够生成基础代码片段的工具, 以及那些逻辑欠缺完整度的静态页面辅助工具, 显著地减少了兴趣。 近日, 国内设计协作“巨头”墨刀, 正式发布了其筹备了很久…

作者头像 李华
网站建设 2026/9/3 0:31:57

8款主流AI论文平台横向实测,本硕博避坑选型手册

前言&#xff1a;AI 写论文乱象频发&#xff0c;实测 8 款工具理清适配边界 每到毕业季&#xff0c;本科生、硕博生都会集中寻找 AI 论文辅助工具&#xff0c;市面各类写作软件层出不穷&#xff0c;但普遍存在几类硬伤&#xff1a;虚假参考文献、无法匹配本校格式、不支持公式代…

作者头像 李华