optiPNG vs PNGcrush vs Gimp to Reduce PNG Size
Which is better? NEITHER! optipng and pngcrush are dated tools, but they are free, and surprisingly still work. Here are some comparisons on compression levels on a PNG file vs the same file as JPG format.
Page load speed is important as a ranking factor in search engines. It makes sense therefore, to optimize your page for speed. While a CDN is probably the better solution, it doesn’t hurt to ALSO optimize your png files.
I was using cygwin and noticed a few tools related to optimizing png files, and how reducing png size:
optipng
pngcrush
I’m used to using other tools such as gimp and ifranview to reduce png size before but thought these tools were worth investigating at least.
TLDR
(Not suprisingly) jpg was a better format for web work but I liked optipng better if I had to choose between pngcrush and optipng. Both beat out gimp, unless I used indexed colors, which only work on specific types of images. Gimp > Export > rename as .jpg, save!
Lossy vs Lossless
JPG is “lossy” meaning, it compresses the data in a way where some of the original data is gone and can never be retrieved. PNG is “lossless” meaning, you can save (nearly) all of the original data.
Transparency
No such thing as a transparent background in jpgs, but PNGs can preserve this layer.
OptiPNG Results
Opti PNG shows me “as-it-happens” as it tries different filters and optimization methods. I liked this. I also like the display of
$ optipng -o7 -keep pngtest.png
** Processing: pngtest.png
500x515 pixels, 4x8 bits/pixel, RGB+alpha
Reducing image to 3x8 bits/pixel, RGB
Input IDAT size = 306918 bytes
Input file size = 307419 bytes
Trying:
zc = 9 zm = 9 zs = 0 f = 1 IDAT size = 287339
zc = 9 zm = 9 zs = 0 f = 2 IDAT size = 283790
zc = 9 zm = 9 zs = 0 f = 3 IDAT size = 276206
zc = 9 zm = 9 zs = 0 f = 4 IDAT size = 274093
zc = 9 zm = 9 zs = 0 f = 5 IDAT size = 273103
Selecting parameters:
zc = 9 zm = 9 zs = 0 f = 5 IDAT size = 273103
Output IDAT size = 273103 bytes (33815 bytes decrease)
Output file size = 273160 bytes (34259 bytes = 11.14% decrease)
PNGcrush results
PNG crush doesn’t give me as much info but it does tell me CPU time, which is nice.
$ pngcrush -brute pngtest.original.png
Recompressing IDAT chunks in pngtest.original.png to pngout.png
Total length of data found in critical chunks = 307419
Best pngcrush method = 118 (ws 15 fm 5 zl 9 zs 0) = 273160
CPU time decode 1.205000, encode 4.921000, other 0.246000, total 6.718000 sec
Smallest PNG Size Results?
$ file pngtest.original.png
pngtest.original.png: PNG image data, 500 x 515, 8-bit/color RGBA, non-interlaced
It is entirely possible that there are different results based on file size, image type, image complexity etc. I didn’t test thoroughly and just picked an image instead.
Original PNG (301k)
Indexed PNG (61k)
Optimized PNG (267k)
JPG (71k)
To be fair though, jpg is lossy, and others are not (with the obvious exception of indexed).
Batch Processing
This wouldn’t even be worth talking about without a way to automate it right? Who wants to manually process 3,142 png files?
$ ls -alFh
-rwxrwx---+ 1 david None 92K Sep 7 10:14 1-barrel-sandponics.png*
-rwxrwx---+ 1 david None 196K Sep 7 10:15 1-barrel-sandponics2.png*
-rwxrwx---+ 1 david None 116K Sep 7 10:16 1-barrel-sandponics-back.png*
-rwxrwx---+ 1 david None 101K Sep 7 10:15 1-barrel-sandponics-bottom.png*
For Loop in Shell
Process all png files using optipng and keep backups. The for loop in the shell uses the f variable to replace the file names on each loop:
$ for f in *.png; do optipng -keep -o7 $f;done
** Processing: 1-barrel-sandponics.png
321x573 pixels, 4x8 bits/pixel, RGB+alpha
Reducing image to 3x8 bits/pixel, RGB
Input IDAT size = 93262 bytes
Input file size = 93381 bytes
Trying:
zc = 9 zm = 9 zs = 0 f = 0 IDAT size = 78323
zc = 9 zm = 8 zs = 0 f = 0 IDAT size = 78238
zc = 9 zm = 9 zs = 0 f = 4 IDAT size = 75392
zc = 9 zm = 9 zs = 0 f = 5 IDAT size = 74314
Selecting parameters:
zc = 9 zm = 9 zs = 0 f = 5 IDAT size = 74314
Output IDAT size = 74314 bytes (18948 bytes decrease)
Output file size = 74421 bytes (18960 bytes = 20.30% decrease)
** Processing: 1-barrel-sandponics2.png
363x747 pixels, 4x8 bits/pixel, RGB+alpha
Reducing image to 3x8 bits/pixel, RGB
Input IDAT size = 200112 bytes
Input file size = 200255 bytes
Trying:
zc = 9 zm = 9 zs = 0 f = 0 IDAT size = 172896
zc = 9 zm = 8 zs = 0 f = 0 IDAT size = 171951
zc = 9 zm = 9 zs = 0 f = 4 IDAT size = 170537
zc = 9 zm = 8 zs = 0 f = 4 IDAT size = 170046
zc = 9 zm = 8 zs = 0 f = 5 IDAT size = 169767
Selecting parameters:
zc = 9 zm = 8 zs = 0 f = 5 IDAT size = 169767
Output IDAT size = 169767 bytes (30345 bytes decrease)
Output file size = 169874 bytes (30381 bytes = 15.17% decrease)
** Processing: 1-barrel-sandponics-back.png
353x545 pixels, 4x8 bits/pixel, RGB+alpha
Reducing image to 3x8 bits/pixel, RGB
Input IDAT size = 117985 bytes
Input file size = 118104 bytes
Trying:
zc = 9 zm = 9 zs = 0 f = 0 IDAT size = 104402
zc = 9 zm = 8 zs = 0 f = 0 IDAT size = 104205
Selecting parameters:
zc = 9 zm = 8 zs = 0 f = 0 IDAT size = 104205
Output IDAT size = 104205 bytes (13780 bytes decrease)
Output file size = 104312 bytes (13792 bytes = 11.68% decrease)
** Processing: 1-barrel-sandponics-bottom.png
393x409 pixels, 4x8 bits/pixel, RGB+alpha
Reducing image to 3x8 bits/pixel, RGB
Input IDAT size = 102431 bytes
Input file size = 102550 bytes
Trying:
zc = 9 zm = 9 zs = 0 f = 0 IDAT size = 89245
Selecting parameters:
zc = 9 zm = 9 zs = 0 f = 0 IDAT size = 89245
Output IDAT size = 89245 bytes (13186 bytes decrease)
Output file size = 89352 bytes (13198 bytes = 12.87% decrease)
After the loop does it’s thing, you have results of the original copied to a .bak file and the new file available for you:
-rw-rw-r--+ 1 david None 73K Oct 13 18:11 1-barrel-sandponics.png
-rwxrwx---+ 1 david None 92K Sep 7 10:14 1-barrel-sandponics.png.bak*
-rw-rw-r--+ 1 david None 166K Oct 13 18:11 1-barrel-sandponics2.png
-rwxrwx---+ 1 david None 196K Sep 7 10:15 1-barrel-sandponics2.png.bak*
-rw-rw-r--+ 1 david None 102K Oct 13 18:12 1-barrel-sandponics-back.png
-rwxrwx---+ 1 david None 116K Sep 7 10:16 1-barrel-sandponics-back.png.bak*
-rw-rw-r--+ 1 david None 88K Oct 13 18:12 1-barrel-sandponics-bottom.png
-rwxrwx---+ 1 david None 101K Sep 7 10:15 1-barrel-sandponics-bottom.png.bak*