aniEle-imge-processor/process_images.py
2025-07-21 10:51:00 +08:00

141 lines
5.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
import os
import re
import sys
import subprocess
import shutil
import tempfile
import zipfile
# --- 配置区 ---
IMAGE_EXTENSIONS = ('.png', '.jpg', '.jpeg', '.bmp', '.gif', '.tiff')
# --- 配置区结束 ---
def check_ffmpeg():
"""检查系统中是否安装了 ffmpeg"""
if shutil.which("ffmpeg") is None:
print("错误:找不到 ffmpeg。")
print("请确保你已经安装了 ffmpeg并将其添加到了系统的 PATH 环境变量中。")
print("安装指南: https://ffmpeg.org/download.html")
return False
return True
def extract_number_from_filename(filename):
"""从文件名中提取最后一个遇到的数字序列用于排序。"""
numbers = re.findall(r'\d+', filename)
if numbers:
return int(numbers[-1])
print(f"警告:文件名 '{filename}' 中未找到数字将按0进行排序。")
return 0
def main():
"""主执行函数"""
print("--- 图片序列转 WebP 并压缩为 ZIP 脚本 (支持自定义起始编号) ---")
# 1. 检查命令行参数 (现在支持3个或4个参数)
if not (3 <= len(sys.argv) <= 4):
print("\n使用方法:")
print(f" python {sys.argv[0]} <源图片文件夹> <输出的ZIP文件名> [<起始编号>]")
print("\n示例 (从0开始):")
print(f" python {sys.argv[0]} ./my_images my_archive.zip")
print("\n示例 (从40开始):")
print(f" python {sys.argv[0]} ./my_images my_archive.zip 40")
sys.exit(1)
source_dir = sys.argv[1]
output_zip_name = sys.argv[2]
# 初始化起始编号为默认值 0
start_index = 0
# 如果提供了第三个参数,则用它作为起始编号
if len(sys.argv) == 4:
try:
start_index = int(sys.argv[3])
if start_index < 0:
print("错误:起始编号不能为负数。")
sys.exit(1)
except ValueError:
print(f"错误:提供的起始编号 '{sys.argv[3]}' 不是一个有效的整数。")
sys.exit(1)
if not output_zip_name.lower().endswith('.zip'):
output_zip_name += '.zip'
# 2. 验证输入
if not check_ffmpeg():
sys.exit(1)
if not os.path.isdir(source_dir):
print(f"错误:源文件夹 '{source_dir}' 不存在或不是一个目录。")
sys.exit(1)
# 3. 查找并排序图片文件
print(f"\n[1/5] 正在扫描文件夹: {source_dir}")
try:
all_files = os.listdir(source_dir)
image_files = [f for f in all_files if f.lower().endswith(IMAGE_EXTENSIONS)]
except OSError as e:
print(f"错误:无法读取文件夹 '{source_dir}': {e}")
sys.exit(1)
if not image_files:
print("指定的文件夹中未找到任何支持的图片文件。")
sys.exit(0)
sorted_images = sorted(image_files, key=extract_number_from_filename)
print("找到并排序后的图片文件:")
for img in sorted_images:
print(f" - {img}")
# 使用临时目录来存放生成的 webp 文件
with tempfile.TemporaryDirectory() as temp_dir:
print(f"\n[2/5] 开始转换图片 (起始编号: {start_index})...")
total_files = len(sorted_images)
# 4. 依次使用 ffmpeg 进行编码
for index, image_name in enumerate(sorted_images):
# 计算最终的输出文件名编号
output_number = start_index + index
output_filename = f"{output_number}.webp"
input_path = os.path.join(source_dir, image_name)
output_path = os.path.join(temp_dir, output_filename)
command = ["ffmpeg", "-i", input_path, "-y", output_path]
print(f" [{index + 1}/{total_files}] 正在转换: {image_name} -> {output_filename}")
try:
subprocess.run(
command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8'
)
except subprocess.CalledProcessError as e:
print(f" 错误: 转换 '{image_name}' 时失败。\n FFmpeg 错误信息:\n{e.stderr}")
except Exception as e:
print(f" 发生未知错误: {e}")
# 5. 将临时目录中的 WebP 文件压缩成 ZIP
print(f"\n[3/5] 正在将 WebP 文件压缩到: {output_zip_name}")
try:
with zipfile.ZipFile(output_zip_name, 'w', zipfile.ZIP_DEFLATED) as zipf:
webp_files_to_zip = sorted(os.listdir(temp_dir), key=lambda f: int(f.split('.')[0]))
for webp_file in webp_files_to_zip:
file_path_in_temp = os.path.join(temp_dir, webp_file)
zipf.write(file_path_in_temp, arcname=webp_file)
print(f" - 已添加 {webp_file} 到 ZIP 包")
except Exception as e:
print(f"错误:创建 ZIP 文件时失败: {e}")
sys.exit(1)
print("\n[4/5] 临时文件已自动清理。")
print(f"\n[5/5] --- 所有任务完成!输出文件已保存为 '{output_zip_name}' ---")
if __name__ == "__main__":
main()