看到你正在整理“暗影花仙精灵王”系列的卡牌图片这种图片素材通常数量多、文件名混乱、格式不统一手动一张张重命名和压缩非常低效。结合我过去的批量图片处理经验整理了一套完整的 Python 批量处理方案可以把图片整理这件事彻底自动化。本文会从实际需求出发带你用 Python 实现“暗影花仙精灵王卡牌图片3”这类批次图片的批量重命名、统一压缩、格式转换和统计归档全程提供可直接复制的代码。1. 背景与核心概念1.1 什么是图片批量处理图片批量处理是指通过脚本或工具一次性对大量图片文件执行相同或相似的操作。常见的操作包括批量重命名将“IMG_20250401_123456.jpg”这种相机默认名改成“暗影花仙精灵王_003.jpg”这种有语义的名字。批量压缩将高分辨率图片等比缩小降低存储占用。批量转换格式比如把 PNG 转为 JPG或者统一输出为 WebP。批量统计统计每个批次图片的数量、尺寸分布、总大小。重复检测找出内容完全相同或接近的图片。在这个需求里“3”通常代表第 3 个批次也就是一批编号连续的卡牌图片素材。我们需要把这一批图片按一定规则归整好。1.2 为什么用 PythonPython 在图片处理领域有非常成熟的生态尤其是 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 安装 PillowPillow 是 Python 中最常用的图像处理库它是 PILPython 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像素模式常见的有RGB、RGBA、L灰度。format原始文件格式例如JPEG、PNG。这是批量处理的基础因为后续的压缩、转换都需要先打开图片。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, quality85)thumbnail会保持图片比例且不会放大图片。这个特性非常适合批量压缩。4. 完整实战案例下面进入核心部分。我们将编写三个脚本rename_images.py批量重命名图片。compress_images.py批量压缩图片。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\scripts4.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(keylambda 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_okTrue) log_file log_dir / rename_log.txt with open(log_file, w, encodingutf-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.py4.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 模式转为 RGBJPG 不支持透明通道 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(parentsTrue, exist_okTrue) img.save(output_path, formatOUTPUT_FORMAT, qualityJPG_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(keylambda p: p.name) if not image_files: print(错误没有找到任何图片文件) return # 输出目录 OUTPUT_DIR.mkdir(parentsTrue, exist_okTrue) 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_okTrue) log_file log_dir / compress_log.txt with open(log_file, w, encodingutf-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))会按比例缩小图片同时保证不超过设定的宽高。quality85是 JPG 保存时的质量参数。对于卡牌图片85 是一个在画质和大小之间比较均衡的取值。日志记录了每张图片压缩前后的体积和尺寸变化方便查看压缩效果。运行脚本cd cards_batch3 python scripts/compress_images.py4.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(keylambda 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_okTrue) with open(OUTPUT_CSV, w, encodingutf-8-sig, newline) as f: fieldnames [文件名, 格式, 宽度, 高度, 文件大小(B)] writer csv.DictWriter(f, fieldnamesfieldnames) 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.py4.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.pyraw目录下是重命名后的原始图片output目录下是压缩后的图片logs目录下是三个脚本生成的日志和清单文件。5. 常见问题与排查思路5.1 重命名时报错“目标文件已存在”问题现象常见原因解决思路重命名时提示目标文件已存在之前可能运行过脚本部分文件已被重命名检查目标文件名对应的日志确认之前是否处理过删除多余文件或调整起始序号如果重复运行重命名脚本第二次运行时会发现暗影花仙精灵王_001.jpg已经存在脚本会跳过。这是设计好的保护逻辑防止覆盖已有文件。5.2 压缩后图片大小反而变大问题现象常见原因解决思路压缩后文件比原图还大原图本身已经是高压缩比的 JPG 或尺寸不大PNG 转 JPG 后质量参数偏高将quality从 85 降到 70 重新压缩或者只在原始图片尺寸较大时才压缩可以将process_image中增加条件判断如果新文件大于旧文件则保留原文件这里需要理解一个概念JPG 是有损压缩如果原始图片已经是质量很高的 JPG再用quality85重新压缩生成的图片可能比原图还大。在实际处理中可以把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, maskimg.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 --user5.5 缩略图没有生效thumbnail方法有一个特点如果图片尺寸本身小于指定尺寸它不会放大图片。也就是说一张400x300的图片即使设置MAX_WIDTH800也不会被放大到800x600。这通常是合理的行为。如果你希望统一尺寸需要用resize并明确指定目标尺寸但这样会改变图片宽高比可能导致卡牌变形。建议优先使用thumbnail。6. 最佳实践与工程建议6.1 操作前先做备份图片处理是不可逆操作。虽然本文脚本的日志会记录原始文件名和新文件名的对应关系但更稳妥的做法是在处理前对整个raw目录做一次备份cp -r raw raw_backupWindows PowerShellCopy-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”这类批次图片进行完整整理的方法用rename_images.py批量重命名图片规则清晰、日志可追溯。用compress_images.py将图片等比压缩控制文件大小。用generate_manifest.py生成图片清单方便核对和交付。这三个脚本组成了一个完整的图片批处理工具链后续可以按需扩展加入图片去重功能使用图像哈希算法检测重复图片。加入 OCR 识别自动识别卡牌名称并作为文件名。加入水印功能批量给图片添加版权水印。接入 Excel 报表生成更美观的图片清单。图片整理是一个基础且高频的需求掌握这套脚本的思路后不管是卡牌图片、摄影素材还是商品图都能套用。建议你先拿少量图片测试确认运行结果符合预期后再处理大批量数据。如果本文对你有帮助可以收藏备用。后续遇到图片处理相关问题也欢迎在评论区交流讨论。
