适用环境
Python 3.10+ 与 Pillow;JPEG / PNG 静态图片
先区分尺寸和质量
一张 6000 像素宽的照片如果只显示在 800 像素的区域,直接发送原图通常浪费传输量。先缩小像素尺寸,再调整压缩质量,比只改文件扩展名有用。本文的 1600 像素和质量 82 是便于起步的示例参数,并非所有图片的最佳值。
准备环境和输入
python -m pip install Pillow在脚本旁新建 photos 文件夹,放入你有权处理的照片;脚本会把副本写入 web_images。安装 Pillow 会下载第三方依赖。建议先用少量图片验证,不覆盖原文件。
完整脚本
from pathlib import Path
from PIL import Image, ImageOps
source = Path('photos')
output = Path('web_images')
output.mkdir(exist_ok=True)
for path in sorted(source.iterdir()):
if path.suffix.lower() not in {'.jpg', '.jpeg', '.png'}:
continue
target = output / (path.name + '.webp')
if target.exists():
print('已存在,跳过:', target)
continue
try:
with Image.open(path) as image:
if getattr(image, 'n_frames', 1) != 1:
print('跳过多帧图片:', path)
continue
image = ImageOps.exif_transpose(image)
image.thumbnail((1600, 1600))
image = image.convert('RGBA' if 'A' in image.getbands() or 'transparency' in image.info else 'RGB')
image.save(target, 'WEBP', quality=82, method=6)
print(path.name, path.stat().st_size, '->', target.stat().st_size)
except (OSError, ValueError) as exc:
print('处理失败:', path.name, exc)为什么这样写
exif_transpose 按照片方向信息旋转,避免手机照片导出后横倒;thumbnail 保持比例且不放大小图;带透明信息的图片转为 RGBA,普通照片转为 RGB。多帧图片跳过,避免把动画悄悄压成第一帧。输出名保留原扩展名,例如 photo.jpg.webp,减少同名不同格式的冲突。
怎样判断压缩是否合格
比较实际文件字节数,在目标显示尺寸和 100% 放大下检查文字边缘、渐变、肤色和透明区域。不要承诺固定压缩比例,简单 PNG、复杂照片和不同质量参数的结果会不同。输出更大时可保留原格式,截图或小字图也可考虑无损方式。
脚本没有覆盖的场景
此脚本不会保留原始拍摄元数据,也没有完整的广色域色彩管理流程;印刷、专业摄影或必须保留定位等元数据的流程应另行处理。WebP 文件能生成不代表所有目标软件都支持,发布前用实际浏览器和接收方软件检查。