Lossless Optimization of PNG Image File Sizes

June 29, 2015

pngout and optipng are command-line utilities for lossless compression (optimization) of PNG image files. Here is a simple example, based on a black and white line plot, r-mle-z.png (source):

% pngout r-mle-z.png
 In:   11150 bytes        r-mle-z.png /c3 /f0 /d8
Out:    8476 bytes        r-mle-z.png /c0 /f5 /d8
Chg:   -2674 bytes ( 76% of original)

In this case, pngout was able to reduce the size by 24% while optipng achieved a reduction of 18% on the same original file:

% optipng -o 7 r-mle-z.png 
** Processing: r-mle-z.png
500x250 pixels, 8 bits/pixel, 256 colors in palette
Reducing image to 8 bits/pixel, grayscale
Input IDAT size = 10301 bytes
Input file size = 11150 bytes

Trying:
  zc = 9  zm = 9  zs = 0  f = 0         IDAT size = 9535
  zc = 9  zm = 9  zs = 1  f = 0         IDAT size = 9325
  zc = 9  zm = 9  zs = 0  f = 2         IDAT size = 9155
  zc = 9  zm = 8  zs = 0  f = 2         IDAT size = 9149
  zc = 9  zm = 9  zs = 1  f = 2         IDAT size = 9079
  zc = 9  zm = 8  zs = 1  f = 2         IDAT size = 9076
  zc = 9  zm = 9  zs = 1  f = 5         IDAT size = 9036
  zc = 9  zm = 8  zs = 1  f = 5         IDAT size = 9032

Selecting parameters:
  zc = 9  zm = 8  zs = 1  f = 5         IDAT size = 9032

Output IDAT size = 9032 bytes (1269 bytes decrease)
Output file size = 9089 bytes (2061 bytes = 18.48% decrease)

From the optipng output above, you can see that it is solving an integer programming problem to select the parameters zc, zm, zs, and f that minimize the file size (IDAT size).

File Sizes in Bytes
Filer-mle-z.pngk.png
Original11,150177,290
pngout8,476132,132
optipng9,089111,444

The table above shows the file sizes, in bytes, resulting from each tool. As you can see, the relative performance of these two tools is file-specific. For a different file, a color screenshot named k.png (source), pngout reduced the size by 26% while optipng reduced it by 37%. So, it’s useful to keep both of these tools at hand.

optipng is available in MacPorts (sudo port install optipng) while to install pngopt you need to download a binary and put it in your path (e.g., in /usr/local/bin). Also be sure to see the tutorial recommend by the author of pngout.