pngquant: Lossy PNG Compression in CI
pngquant --quality=65-80 image.png converts a 24-bit PNG to an 8-bit palette, often cutting size by 60-70% with minimal visible loss.
pngquant trades a little quality for big size wins by palette-reducing PNGs. Its quality range and its meaningful exit codes are the key things to handle in CI.
What it does
pngquant requantizes a truecolor PNG down to a palette (up to 256 colors) using dithering, which is lossy but usually imperceptible. --quality=min-max sets the acceptable range; if it cannot meet the minimum it skips the file and exits 99 by default.
Common usage
# write image-fs8.png next to the original
pngquant --quality=65-80 image.png
# overwrite the input file in place
pngquant --quality=65-80 --ext .png --force image.png
# fastest pass, batch a folder
pngquant --speed 1 --quality=60-85 *.pngOptions
| Flag | What it does |
|---|---|
| --quality=min-max | Acceptable quality range (0-100) |
| --ext <suffix> | Output suffix; use .png with --force to overwrite |
| --force / -f | Overwrite existing output |
| --speed <1-11> | Speed/quality tradeoff (1 slowest/best) |
| --strip | Remove metadata |
| --skip-if-larger | Do not write output if it would be bigger |
In CI
pngquant exits 99 when it cannot reach --quality minimum and 98 on a quality-too-low abort; a naive set -e script then fails the whole job. Guard with || true or widen the quality range. Use --skip-if-larger so already-small PNGs are not bloated.
Common errors in CI
"pngquant: command not found" means install pngquant (apt-get install -y pngquant). Exit code 99 with "quality too low" is the documented "could not meet --quality" signal, not a crash; lower the minimum or handle the code. "error: too many colors" no longer applies (it auto-quantizes), but "cannot open file" is a path error. By default it writes name-fs8.png, so pipelines expecting in-place edits must pass --ext .png --force.