Information Technology Grimoire

Version .0.0.1

IT Notes from various projects because I forget, and hopefully they help you too.

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)

Original File

Indexed PNG (61k)

Indexed

Optimized PNG (267k)

optimized PNG

JPG (71k)

To be fair though, jpg is lossy, and others are not (with the obvious exception of indexed). jpg

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*
Last updated on 13 Oct 2020
Published on 13 Oct 2020