PNG 批量压缩

SkillMedia

Batch PNG compression for app projects. Uses pngquant for quantization and oxipng for lossless finalization, with content caching and quality gates to avoid recompression and visible degradation. Use when given a project or image directory, a request to reduce bundle size, or a request to batch-comp

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the PNG 批量压缩 skill

What this skill tells your AI

The instructions your AI receives, as published by job-yang/jobyang-ai-skills in skills/png-compress-skill/SKILL.md and read by ahel’s review.

这个技能能做什么

给它一个 App 工程或普通图片目录,它会:

  1. 自动递归找出所有 PNG(自动跳过 Pods / Carthage / build / DerivedData 等目录)
  2. 自动判断压没压过——用文件内容 hash 存本地缓存,压过的直接跳过,绝不二次量化毁图
  3. 自动压缩新增/改动的图,增量持续可用(缓存可提交进仓库,团队/CI 共享)
  4. 小图友好——20K 以下 icon 用更保守的质量下限,避免糊
  5. 变大回退——压完比原图还大就丢弃,保留原图(icon 常见)
  6. 压后自检——默认校验可解码/宽高不变/alpha 不丢,再用 PSNR/SSIM/MAE 做自动质量门禁;不通过就回退原图
  7. 动图保护——检测到 APNG 直接保留原图,不把动画误压成单帧
  8. 原地覆盖,不依赖具体 App、Target 或构建系统;多进程跑满 CPU

内核 = pngquant(有损量化,24/32bit → 8bit 调色板)+ oxipng(无损重编码和元数据清理)。这条路线与 TinyPNG 官方公开的“颜色量化 + 元数据清理”原理一致,但不声称复刻其未公开实现。

适用范围

  • 不读取 .xcodeproj、Scheme、Bundle ID 或业务源码,不依赖任何特定业务工程或私有构建设施。
  • 只要目录里有 PNG 就能运行;默认排除依赖目录和构建产物。
  • 目标是 iOS App 源码资源,同样可以用于其他 App 或独立图片目录。
  • 只处理静态 PNG;检测到 APNG 会保留原图。

怎么用

最简单:一键跑当前目录

./compress.sh

不传目录 = 默认当前目录递归。依赖(pngquant / oxipng)缺失时会自动尝试用 brew 安装。

指定工程目录

./compress.sh /path/to/iOSProject

只看效果不改文件(先预估收益)

./compress.sh /path/to/iOSProject --dry-run

指定并行数

./compress.sh /path/to/iOSProject -j 8

输出长啥样

扫描到 PNG: 1234 张 | 缓存已记录: 0 张 | 并行: 8
自检门禁: hard=on | quality=on | ssim=on
===== 完成 =====
压缩: 900  跳过(缓存): 0  保留原图(压不动): 330  跳过(APNG): 4  硬门禁回退: 0  质量门禁回退: 2  失败: 0
本轮压缩前: 45.2MB  压缩后: 12.8MB  节省: 32.4MB (71.7%)
耗时: 38.5s

再跑第二次,压过的全部走"跳过(缓存)",秒回。


实现细节(感兴趣再看)

脚本本体是 compress_images.py,compress.sh 只是加了依赖自检 + 自动安装的一层壳,两个交付形态(纯脚本 / 技能)复用同一份 compress_images.py

核心命令(每张图):

# ① 有损量化,达不到质量或变大就放弃(退出码 98/99 视为正常)
pngquant --quality 65-85 --speed 1 --floyd=1.0 --strip --skip-if-larger \
         --force --output out.png  input.png
# ② 无损收尾:榨 DEFLATE + 删所有元数据
oxipng -o max --strip all -q out.png

压后自检(默认开启):

  1. 硬门禁: 用 Pillow(没有则退到 macOS sips)解码原图和候选图,要求候选图可解码、宽高不变、原图有 alpha 时候选图不能丢 alpha、动画帧数不能变化。
  2. 质量门禁: 用 Pillow 计算 before/after 像素差异。默认阈值是 PSNR >= 28SSIM >= 0.95(有 numpy 时启用)、MAE <= 12alpha MAE <= 3。透明图会分别垫白底/黑底对比,避免只看透明像素导致误判。
  3. 动图保护: APNG 不进入有损量化,直接保留并写入缓存。
  4. 回退策略: 任何门禁不通过都保留原图,并把原图 hash 记入缓存,下次不再重复尝试。输出会打印 [HARD-GATE][QUALITY-GATE] 的文件清单。

这套自动门禁只负责拦“坏图/尺寸变了/alpha 丢了/明显灾难性劣化”。“到底糊不糊”仍然有主观性,建议每轮再按体积下降最大、压缩比例最高、AppIcon/launchscreen、透明 icon 等维度做肉眼抽检。

可调参数(在 compress_images.py 顶部):

参数默认值说明
QUALITY_NORMAL65-85普通图质量区间,上限对齐 TinyPNG 观感
QUALITY_SMALL70-90小图/icon 区间,下限抬高防糊
SMALL_THRESHOLD20*102420KB 以下算小图
DITHER1.0抖动强度,TinyPNG 默认开启
OXIPNG_LEVELmax无损级别,嫌慢可改 4
CACHE_NAME.png_compress_cache.json缓存文件,建议提交进仓库
QUALITY_MIN_PSNR28.0自动质量门禁最低 PSNR
QUALITY_MIN_SSIM0.95自动质量门禁最低 SSIM(有 numpy 时启用)
QUALITY_MAX_MAE12.0自动质量门禁最大平均绝对误差
QUALITY_ALPHA_MAX_MAE3.0透明通道最大平均绝对误差

Python 直接调用:

python3 compress_images.py                       # 当前目录递归
python3 compress_images.py /path/to/iOSProject   # 指定目录
python3 compress_images.py /path/to/proj --dry-run
python3 compress_images.py /path/to/proj -j 8
python3 compress_images.py /path/to/proj --no-quality-gate       # 关闭质量门禁(不建议)
python3 compress_images.py /path/to/proj --quality-min-ssim 0.98  # 调高质量阈值

依赖手动安装:

  • macOS:brew install pngquant oxipng
  • Ubuntu:sudo apt-get install pngquant + cargo install oxipng(或下 GitHub release 二进制)
  • 自检: 硬门禁可用 macOS 自带 sips;质量门禁默认开启且需要 Python Pillow,有 numpy 时会额外启用 SSIM 指标。缺 Pillow 时脚本会报错,除非显式加 --no-quality-gate

Signals

GitHub stars
79
Forks
3
Last commit
Sep 2026

ahel review

  • K1binfo
    installs-packages
  • K1binfo
    installs-packages (in compress.sh)
  • K1binfo
    installs-packages (in compress_images.py)
  • K1binfo
    installs-packages (in README.en.md)
  • K1binfo
    installs-packages (in README.md)

Automated review, not a security audit. Ruleset v1+k2.

Advanced
Catalog kind
skill
Gateway key
png-compress
Source
github.com/job-yang/jobyang-ai-skills