Program to lossily compress PNG images using adaptive quantization.
This code preprocesses PNG images by making small changes to the images to make them easier to compress. The program uses adaptive quantization based on the local noisiness of the source image, taking advantage of noise masking. It is designed for the "Average" predictor in PNG - various predictors were tried, but "Average" worked out best as it smeared out any effects of quantization. The program quantizes to the highest power of 2 within the allowable noise margin, unless a recent value was used that also results in output within the allowable noise margin (to make use of DEFLATE's runlength encoding).
The nonlinear formula for allowable error at each compression and noise level was chosen based on careful trial and error and hand tuning for optimal visual perceptual effect.
The program ended up being similar to lossypng, but the adaptive quantization used in xpng makes it better at low compression levels (achieving compression ratios of 5-10 compared to raw without significant visual artifacts, as shown in the sample images below). This minimal-artifact compression ratio of 5-10 for XPNG compares with roughly 15-20 for JPEG. However, XPNG performs much better than JPEG on images containing a mixture of photography and text or line art.
xpng inputfile.png outputfile.png [compressionlevel] [radius]
(compression level is a number from 0-255, with a typical value of 32(default), radius noise is a number from 1-16, with a typical value of 2(default))
Apply a png optimizer afterwards for full compression.
Requires libpng and zlib.
Compile with make
or gcc xpng.c -o xpng -lpng -lz -lm
Here is a diverse suite of test images fromm the Kodak Image Suite. Both original and compressed versions were run through PNGGauntlet for an optimized apples to apples comparison. A comprssion level of 6 was used. The compressed image follows the original.