图片压缩工具箱
成品文件公式:用户给图片 → 拿到压好的图片文件(不是教程,不是参数建议)。核心刚需:报名系统/考试报名/证件上传卡"不超过 200KB / 500KB";电商卖家批量压商品图。全程本地处理(Pillow),无需网络与 API Key。
功能
| 子命令 | 用途 | 典型场景 |
|---|---|---|
to-size |
单张压到指定 KB | 报名照片压到 200KB/500KB 以内 |
batch |
整目录批量压缩 | 电商商品图、相册批量压图 |
convert |
格式转换 jpg/png/webp | 大 PNG 转 webp/jpg 瘦身 |
脚本内置策略(agent 无需操心):
- 质量二分(95→10)找"达标的最大质量";仍超标 → 等比缩宽(×0.75)再二分,循环直到达标,全程保持宽高比
- PNG 兜底:PNG 是无损格式,auto 模式下原尺寸 optimize 压不到位时自动转 JPG(透明处铺白底)并打印说明
- 动图保护:GIF/WebP 动图自动跳过(压缩/转格式都会丢帧),batch 中计入"跳过"
- 保守口径:目标按 1KB=1000B 计算,上传系统无论按 1000 还是 1024 校验都能通过
- EXIF:自动按 EXIF 方向摆正(手机竖拍不横倒),不保留 EXIF(体积更小)
工作流程
- 拿三要素:①目标大小(200KB?500KB?)②图片路径 ③是否限定输出格式。用户没说目标大小时:报名/上传类场景默认
--target 200,并告知"需要其他上限(如 500KB)随时说"。 - 执行命令(一律用绝对路径):
bash
SKILL_DIR="$HOME/.workbuddy/skills/img-compress-toolbox"
[ -f "$SKILL_DIR/scripts/img_compress.py" ] || SKILL_DIR="$PWD/.workbuddy/skills/img-compress-toolbox"
[ -f "$SKILL_DIR/scripts/img_compress.py" ] || SKILL_DIR="/sandbox/workspace/skills/img-compress-toolbox"
S="$SKILL_DIR/scripts/img_compress.py"
python3 $S to-size /path/照片.jpg --target 200 -o /path/照片_报名版.jpg
- 交付:命令会打印"原始 X → 压缩后 Y(宽a→宽b,质量q)",把输出文件的绝对路径 + 实际大小报给用户即可,无需解释技术细节。
- 出现 ⚠️ 警告时(已压到极限仍超目标,exit code=1):如实告知用户,给出两个选项——放宽目标 / 接受极限结果;不要静默交付。
- 文件夹 → 用 batch:交付时报告汇总行(达标/跳过/失败)和输出目录;个别动图被跳过属正常,说明一句即可。
- 只转格式、不设大小 → 用 convert:若输出提示"转换后比原文件更大",说明用户给的源本身较小,建议改用 to-size。
命令参考
S="$SKILL_DIR/scripts/img_compress.py"
# 1) 压到指定大小(核心命令)
python3 $S to-size 照片.jpg --target 200 -o out.jpg
# --target 目标 KB 数(必填)
# -o 输出路径(默认:原名_min.扩展名)
# --format jpg/png/webp(默认跟随原图;PNG 压不到位自动转 JPG)
# 2) 批量压缩整个目录
python3 $S batch ./photos --target 200 -d ./photos_out --format jpg
# --target 目标 KB 数(默认 200)
# -d 输出目录(默认:<目录名>_compressed,自动创建)
# --format 统一输出格式(默认各图跟随原图);不递归子目录
# 3) 格式转换
python3 $S convert in.png --format webp -q 85
# --format jpg/png/webp(必填)
# -q 质量 1-95,默认 85(仅 jpg/webp 生效;PNG 忽略)
# -o 输出路径(默认:同名换扩展名)
示例对话
例 1:报名照片压到 200KB
> 用户:这张照片 3MB,报名系统要求 200KB 以内,帮我压一下
> Agent:(执行 to-size 照片.jpg --target 200 -o 照片_报名版.jpg)
> "压缩完成:原始 3.7MB → 195KB(宽3000→宽1687,质量20)。文件在 ./照片_报名版.jpg,可以直接上传。"
例 2:批量压商品图
> 用户:./商品图 文件夹里的图全都太大,统一压到 500KB 以内
> Agent:(执行 batch ./商品图 --target 500 -d ./商品图_compressed)
> "48 张全部达标,输出在 ./商品图_compressed;其中 2 张 GIF 动图已跳过(避免丢帧)。"
例 3:格式转换
> 用户:把这张 png 转成 webp,别太糊
> Agent:(执行 convert in.png --format webp -q 85)
> "已转换:in.png → in.webp(原始 4.1MB → 620KB)。"
运行环境
- 脚本:
scripts/img_compress.py(相对技能根目录) - Python:3.9+
- 第三方库:
Pillow(pip install Pillow)
开工前先跑一次自检,缺什么当场补,别等跑到一半报错:
python3 -c "import PIL" 2>/dev/null || echo "缺 Pillow,请执行 pip install Pillow"
> 缺依赖时用中文告诉用户缺什么、装完就能用,不要把 Python 的英文 traceback 原样贴给用户。
注意事项
- PNG 规则:auto 模式下先原尺寸 optimize,压不到位自动转 JPG(透明铺白底)并打印说明;显式
--format png则尊重用户选择,只做 optimize+缩宽,压不到会警告。 - 动图:GIF/WebP 动图一律跳过(to-size/convert/batch 均如此),避免丢帧;需要动图压缩时明确告知用户需单独处理。
- 极限警告:极端小目标(如 <5KB)或噪点极高的图,缩到宽 100px 仍可能不达标,此时输出极限结果、exit code=1,agent 应如实告知。
- 口径说明:目标按 1KB=1000B(保守);打印的 KB 数按 1024 显示,实际只会更小,可放心承诺"能过校验"。
- 不支持:视频压缩(用 video-toolbox)、裁剪/水印/美颜、网络图片下载;GIF 动图压帧不在范围内。
- 依赖:仅 Pillow(Pillow 11.3.0,当前运行环境自带)与标准库;支持输入 jpg/jpeg/png/webp/bmp/tiff/gif。