用Python脚本批量将图片转换为WebP格式

用Python脚本批量将图片转换为WebP格式

在网页开发和移动应用中,WebP格式因其高压缩率和高质量图像表现逐渐取代了传统的PNG和JPEG格式。WebP格式不仅能显著减少图片体积,还能在保持图像清晰度的同时节省存储空间和带宽。对于需要批量处理图片的开发者或设计师来说,使用Python脚本自动化转换图片格式是一个高效且灵活的解决方案。本文将详细介绍如何利用Python脚本实现批量将图片转换为WebP格式,并提供完整的代码示例和优化建议。

1. 环境准备

在开始编写脚本之前,需要确保开发环境满足以下条件:

  1. Python环境
    Python 3.x版本(推荐3.8及以上)。可以通过命令 python --version 或 python3 --version 检查版本。
  2. 安装依赖库
  • Pillow:Python Imaging Library(PIL)的分支,用于图像处理
    安装命令:
    bash pip install Pillow
  • argparse:Python标准库,用于解析命令行参数(无需额外安装)。
  • concurrent.futures:Python标准库,用于实现多线程并发处理(无需额外安装)。
  1. 支持的输入格式
    脚本将支持常见的图片格式,如PNG、JPEG、BMP、TIFF、GIF等。

2. 脚本功能概述

目标是编写一个Python脚本,实现以下功能:

  1. 批量处理:遍历指定目录下的所有图片文件,自动转换为WebP格式。
  2. 参数支持
  • 指定输入目录和输出目录。
  • 设置图片压缩质量(默认80)。
  • 控制并发线程数(默认1,最大不超过CPU核心数)。
  1. 并发处理:利用多线程加速批量转换过程。
  2. 错误处理:跳过损坏的图片文件,并记录日志。

3. 详细实现步骤

3.1 导入必要的库

import os
from PIL import Image
import argparse
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor

3.2 解析命令行参数

使用 argparse 库定义脚本的参数选项:

def parse_args():
parser = argparse.ArgumentParser(description="批量转换图片为WebP格式")
parser.add_argument("-i", "--input", type=str, default=os.getcwd(), help="输入目录(默认为当前目录)")
parser.add_argument("-o", "--output", type=str, default=os.getcwd(), help="输出目录(默认为当前目录)")
parser.add_argument("-q", "--quality", type=int, default=80, help="WebP压缩质量(0-100,默认80)")
parser.add_argument("-t", "--threads", type=int, default=1, help="并发线程数(默认1,最大不超过CPU核心数)")
return parser.parse_args()

3.3 遍历目录并筛选文件

定义函数遍历输入目录,筛选支持的图片格式:

def get_image_files(input_dir):
supported_extensions = {".png", ".jpg", ".jpeg", ".bmp", ".tiff", ".gif"}
image_files = []
for root, dirs, files in os.walk(input_dir):
for file in files:
ext = Path(file).suffix.lower()
if ext in supported_extensions:
image_files.append(os.path.join(root, file))
return image_files

3.4 图片转换逻辑

定义核心的转换函数,将单张图片保存为WebP格式:

def convert_image(input_path, output_dir, quality):
try:
# 打开图片
with Image.open(input_path) as img:
# 构建输出路径
output_filename = Path(input_path).stem + ".webp"
output_path = os.path.join(output_dir, output_filename)
# 确保输出目录存在
os.makedirs(output_dir, exist_ok=True)
# 保存为WebP格式
img.save(output_path, "WEBP", quality=quality)
print(f"已转换: {input_path} -> {output_path}")
except Exception as e:
print(f"转换失败: {input_path} - {e}")

3.5 并发处理

使用 ThreadPoolExecutor 实现多线程并发处理:

def convert_images_concurrently(image_files, output_dir, quality, max_threads):
with ThreadPoolExecutor(max_workers=max_threads) as executor:
futures = []
for input_path in image_files:
futures.append(executor.submit(convert_image, input_path, output_dir, quality))
# 等待所有任务完成
for future in concurrent.futures.as_completed(futures):
future.result()

4. 完整脚本代码

将上述模块整合为完整的脚本:

import os
from PIL import Image
import argparse
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed
def parse_args():
parser = argparse.ArgumentParser(description="批量转换图片为WebP格式")
parser.add_argument("-i", "--input", type=str, default=os.getcwd(), help="输入目录(默认为当前目录)")
parser.add_argument("-o", "--output", type=str, default=os.getcwd(), help="输出目录(默认为当前目录)")
parser.add_argument("-q", "--quality", type=int, default=80, help="WebP压缩质量(0-100,默认80)")
parser.add_argument("-t", "--threads", type=int, default=1, help="并发线程数(默认1,最大不超过CPU核心数)")
return parser.parse_args()
def get_image_files(input_dir):
supported_extensions = {".png", ".jpg", ".jpeg", ".bmp", ".tiff", ".gif"}
image_files = []
for root, dirs, files in os.walk(input_dir):
for file in files:
ext = Path(file).suffix.lower()
if ext in supported_extensions:
image_files.append(os.path.join(root, file))
return image_files
def convert_image(input_path, output_dir, quality):
try:
with Image.open(input_path) as img:
output_filename = Path(input_path).stem + ".webp"
output_path = os.path.join(output_dir, output_filename)
os.makedirs(output_dir, exist_ok=True)
img.save(output_path, "WEBP", quality=quality)
print(f"已转换: {input_path} -> {output_path}")
except Exception as e:
print(f"转换失败: {input_path} - {e}")
def main():
args = parse_args()
# 限制线程数不超过CPU核心数
max_threads = min(args.threads, os.cpu_count() or 1)
print(f"使用 {max_threads} 个线程进行转换")
# 获取所有图片文件
image_files = get_image_files(args.input)
if not image_files:
print("未找到支持的图片文件。")
return
# 并发转换
convert_images_concurrently(image_files, args.output, args.quality, max_threads)
if __name__ == "__main__":
main()

5. 使用示例

  1. 基本用法
    转换当前目录下的所有图片到同级目录:
python convert_to_webp.py
  1. 指定输入输出目录
    将图片转换到指定的输出目录:
python convert_to_webp.py -i ./images -o ./webp_output
  1. 调整压缩质量
    设置压缩质量为90:
python convert_to_webp.py -q 90
  1. 多线程并发
    使用4个线程加速转换:
python convert_to_webp.py -t 4

6. 优化与扩展

  1. 支持更多格式
    可以通过修改 supported_extensions 增加对其他格式的支持,例如HEIC或SVG。
  2. 图形界面
    使用 tkinter 或 PyQt 为脚本添加图形化界面,方便非技术用户操作。
  3. 日志记录
    将转换结果和错误信息记录到日志文件中,便于后续分析。
  4. 进度条
    使用 tqdm 库显示转换进度,提升用户体验。
  5. 自动清理
    添加选项在转换完成后删除原始图片,节省存储空间。

7. 总结

通过本文的实践,我们实现了一个功能完善的Python脚本,能够高效批量将图片转换为WebP格式。该脚本结合了多线程并发处理和灵活的参数配置,适用于从个人项目到企业级图像管理的多种场景。WebP格式的优势在于其高压缩率和高质量图像表现,结合自动化脚本后,可以显著提升图片处理效率,降低存储和传输成本。对于需要频繁处理图片的开发者和设计师来说,这是一个值得尝试的工具。

阅读剩余