我的知识记录

Python 批量压缩图片体积:在清晰度和大小之间找平衡

用 Python Pillow 批量压缩图片,通过调整 quality 参数、optimize、转 WebP 把大图压小,支持遍历目录、对比压缩前后体积,附完整代码和注意事项。

场景痛点

单反拍的原图一张 5-10MB,手机相册导出的图也动不动 3-5MB,传到网站、邮件附件、微信群里都太慢。用 Photoshop 一张张导出,几十张图要点到手酸,还记不住每张压到多少合适。用 Python 批量跑一遍,统一把体积压到目标范围,肉眼几乎看不出差别,文件能小 60%-80%。

用到的库

pip install Pillow

完整代码

import os
from PIL import Image

SRC_EXTS = (".jpg", ".jpeg", ".png", ".webp")


def human_size(n):
"""把字节数转成可读字符串"""
for unit in ("B", "KB", "MB"):
if n < 1024:
return f"{n:.1f}{unit}"
n /= 1024
return f"{n:.1f}GB"


def compress_one(src_path, dst_path, quality=80):
"""压缩单张图片,quality 1-95,越大越清晰"""
img = Image.open(src_path)
# PNG 带透明通道,压 JPEG 会丢透明,统一处理
if img.mode not in ("RGB", "L"):
img = img.convert("RGB")
img.save(dst_path, "JPEG", quality=quality, optimize=True, progressive=True)
old = os.path.getsize(src_path)
new = os.path.getsize(dst_path)
ratio = (1 - new / old) * 100 if old else 0
print(f"{os.path.basename(src_path)}: {human_size(old)} -> {human_size(new)},减小 {ratio:.1f}%")


def batch_compress(src_dir, dst_dir, quality=80):
"""批量压缩目录下所有图片,输出为 JPEG"""
os.makedirs(dst_dir, exist_ok=True)
for root, _, files in os.walk(src_dir):
for name in files:
if not name.lower().endswith(SRC_EXTS):
continue
src_path = os.path.join(root, name)
rel = os.path.relpath(src_path, src_dir)
new_name = os.path.splitext(rel)[0] + ".jpg"
dst_path = os.path.join(dst_dir, new_name)
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
try:
compress_one(src_path, dst_path, quality)
except Exception as e:
print(f"失败:{src_path},原因:{e}")


def main():
src_dir = "./photos"
dst_dir = "./photos_compressed"
batch_compress(src_dir, dst_dir, quality=80)


if __name__ == "__main__":
main()

代码讲解

  • quality=80 是 JPEG 压缩关键参数,范围 1-95,常用 75-85。80 是人眼基本看不出差别、体积又小的甜点位。
  • optimize=True 让 Pillow 先扫描整张图选最优 Huffman 表,文件再小一点点,代价是慢一点。
  • progressive=True 生成渐进式 JPEG,网页加载时先模糊后清晰,做网站时推荐开。
  • img.convert("RGB") 把 RGBA、P 模式统一转 RGB,否则存 JPEG 直接报错。
  • human_size 把字节数转成 KB/MB,方便控制台对比压缩效果。
  • 脚本同时打印每张图压缩前后体积和减小百分比,跑完一眼能看到压缩率。

运行结果

运行后在 ./photos_compressed 下生成同名 .jpg 文件,控制台逐张打印压缩前后大小和减小百分比。跑完挑几张原图和压缩图放一起对比,确认清晰度能接受。

注意事项

  • quality 调到 60 以下会出现明显色块,人像、文字图不建议低于 75。
  • PNG 截图类内容压成 JPEG 会有噪点,想保留画质就用 WebP:把保存格式改成 WEBP,quality 同样有效。
  • 已经是小图(<100KB)压了反而可能变大,脚本没做这层判断,建议手动过滤一下小文件。
  • 原图保留在原目录,脚本只写输出目录,跑坏了随时重跑。

Python 批量压缩图片体积:在清晰度和大小之间找平衡

标签:

更新时间:2026-09-14 20:44:48

上一篇:Python 批量生成二维码:从 CSV 读取数据一键出图

下一篇:Python 开机自启脚本设置:Windows 启动项与 Linux systemd