PNG Image Optimization for Reduced File Sizes
June 28th, 2009 Alex Moffat
Inspired by the third part of Stoyan Stefanov’s series about Image Optimization I decided to see what I could do with the PNG images in Blueprint. Stoyan suggests four possible programs to use, pngcrush, pngrewrite, OptiPNG and PNGOut. I was unable to compile pngrewrite so I ended up with three possibilities which I tried on all of the files to see how they performed. It turns out, that for our images at least, there is no clear winner, some files compress better with one program and others with another. The best any individual program could achieve was an overall reduction of 12% across all the files while picking the best program for each file produced a reduction of 17%.
Total size of original files 133368 bytes.
0 files could not be reduced in size.
pngcrush
If used as only reducer saves 14887 bytes = 11%.
Was the best method for 68 files, saving 9943 bytes.
OptiPNG
If used as only reducer saves 13742 bytes = 10%.
Was the best method for 1 files, saving 163 bytes.
PNGOut
If used as only reducer saves 17148 bytes = 12%.
Was the best method for 16 files, saving 13789 bytes.
Maximum possible reduction 23895 bytes = 17%.
Out of interest I ran the test again over the optimized files to see if further reductions could be obtained, for instance if OptiPNG could further reduce a file that pngcrush had reduced.
Total size of original files 109473 bytes.
68 files could not be reduced in size.
pngcrush
If used as only reducer saves 50 bytes = 0%.
Was the best method for 2 files, saving 48 bytes.
OptiPNG
If used as only reducer saves 162 bytes = 0%.
Was the best method for 15 files, saving 151 bytes.
PNGOut
If used as only reducer saves 0 bytes = 0%.
Was the best method for 0 files, saving 0 bytes.
Maximum possible reduction 199 bytes = 0%.
The answer apparently is that you really don’t get any worthwhile size reduction from a second pass.
Originally I wrote a Ruby program to run these test, after all everyone knows Java is no good for invoking command line programs! Well, that’s not true. After getting the Ruby version working in a basic way I switched over to Java. With a decent IDE I can write Java faster than I can write Ruby and Runtime.getRuntime().exec() is a great way to run command lines. I even included some gratuitous use of ExecutorCompletionService from java.util.concurrent to be able to run the optimizations for each file in parallel.
Posted in Web | No Comments »