Until recently, I didn’t have a clue you can compress PNG images on a Linux command line. if you are a terminal centric Linux user, then this article is for you. Image compression is critical for faster website loading. pngquant is a command-line utility and a library for lossy compression of PNG images.

compress png images

pngquant can reduce the size of the PNG image by up to 70% while preserving full alpha transparency. Generated images are compatible with all web browsers and operating systems.

Features of pngquant

  • Fast mode for real-time processing/large numbers of images.
  • High-quality palette generation using a combination of vector quantization algorithms.
  • Easy to integrate with shell scripts, GUIs and server-side software.
  • Unique adaptive dithering algorithm that adds less noise to images than the standard Floyd-Steinberg.

Installing pngquant on Linux

pngquant can be installed from your OS upstream repository or by compiling it from source code. The advantage of building pngquant from source is that you get the latest release as opposed to packages available on the system repository.

Install pngquant on CentOS / Fedora

First install required dependencies.

sudo yum -y install git libpng-devel gcc cmake

Then clone pngquant project from git.

git clone --recursive https://github.com/kornelski/pngquant.git

Run ./configure and make to generate pngquant executable in the current directory.

cd pngquant
./configure
make

If you’d like to install it system-wide, run the command:

sudo make install

The binary file will be copied to /usr/local/bin/pngquant

$ pngquant --version
2.12.2 (November 2018)

Install pngquant on Ubuntu / Debian

Install required dependencies

sudo apt-get update
sudo apt-get install -y git gcc cmake libpng-dev pkg-config

Clone pngquant

git clone --recursive https://github.com/kornelski/pngquant.git

Install it by running the commands below

cd pngquant
./configure
make
sudo make install

Install pngquant on Arch Linux / Manjaro

The latest version of pngquant can be installed on Arch Linux using pacman command.

sudo pacman -S pngquant

Using pngquant on Linux CLI

You can print all pngquant options using --help option.

$ pngquant --help
pngquant, 2.12.2 (November 2018), by Kornel Lesinski, Greg Roelofs.
   Compiled with no support for color profiles. Using libpng 1.6.34.

usage:  pngquant [options] [ncolors] -- pngfile [pngfile ...]
        pngquant [options] [ncolors] - >stdout <stdin

options:
  --force           overwrite existing output files (synonym: -f)
  --skip-if-larger  only save converted files if they're smaller than original
  --output file     destination file path to use instead of --ext (synonym: -o)
  --ext new.png     set custom suffix/extension for output filenames
  --quality min-max don't save below min, use fewer colors below max (0-100)
  --speed N         speed/quality trade-off. 1=slow, 4=default, 11=fast & rough
  --nofs            disable Floyd-Steinberg dithering
  --posterize N     output lower-precision color (e.g. for ARGB4444 output)
  --strip           remove optional metadata (default on Mac)
  --verbose         print status messages (synonym: -v)

Quantizes one or more 32-bit RGBA PNGs to 8-bit (or smaller) RGBA-palette.
The output filename is the same as the input name except that
it ends in "-fs8.png", "-or8.png" or your custom extension (unless the
input is stdin, in which case the quantized image will go to stdout).
If you pass the special output path "-" and a single input file, that file
will be processed and the quantized image will go to stdout.
The default behavior if the output file exists is to skip the conversion;
use --force to overwrite. See man page for full list of options.

Example 1

In my laptop, I have a 3.9 MB PNG image that I’ll compress with pngquant.

$ du -sh wallpaper-01.png
3.9M    wallpaper-01.png

A basic example of compressing an image with pngquant is:

$ pngquant --force --quality=40-100 --strip --skip-if-larger --verbose wallpaper-01.png 
 wallpaper-01.png:
   read 3893KB file
   used gAMA and cHRM chunks to transform image to sRGB colorspace
   made histogram…231676 colors found
   selecting colors…14%
   selecting colors…28%
   selecting colors…100%
   moving colormap towards local minimum
   eliminated opaque tRNS-chunk entries…0 entries transparent
   mapped image to new colors…MSE=6.201 (Q=79)
   writing 256-color image as wallpaper-01-fs8.png
 Quantized 1 image.

Check the size of the destination file `

$ du -sh wallpaper-01-fs8.png
1.4M    wallpaper-01-fs8.png

You can see the size is 1.4 MB. This is a reduction of 2.5 MB, quite impressive.

If you want to overwrite the original file with the convered one, use the --output file option.

$ pngquant --force --quality=40-100 --strip --skip-if-larger \
--verbose --output wallpaper-01.png  wallpaper-01.png 
 wallpaper-01.png:
   read 3893KB file
   used gAMA and cHRM chunks to transform image to sRGB colorspace
   made histogram…231676 colors found
   selecting colors…6%
   selecting colors…12%
   selecting colors…50%
   selecting colors…87%
   selecting colors…100%
   moving colormap towards local minimum
   eliminated opaque tRNS-chunk entries…0 entries transparent
   mapped image to new colors…MSE=6.111 (Q=79)
   writing 256-color image as wallpaper-01.png
 Quantized 1 image.
 

Confirm:

$ du -sh wallpaper-01.png
 1.4M    wallpaper-01.png

Example 2: Compressing Multiple PNG images

If in your current folder you have multiple PNG images, you can use a bash for loop to compress all items.

for i in *.png; do
  pngquant --force --quality=40-100 --strip --skip-if-larger \
--verbose $i
done

Example 3: Search for all PNG images in a directory and compress.

You can also use the Linux find command to locate all PNG images in a specified directory and compress then inline.

find /mysite/wp-content/uploads/ -type f -iname '*.png' -exec \
pngquant --force --quality=40-100 --skip-if-larger --strip --verbose {} --output {} \;

Replace /mysite/wp-content/uploads/ with the path to search through recursively.

In our next guide, we will cover compression of JPEG image types on the Linux command line. Until then. check:

LEAVE A REPLY

Please enter your comment!
Please enter your name here