How to optimize PNG images#
PNG is a lossless image format that supports transparency. It is a good alternative to JPEG for images with a lot of detail and/or transparency. However, PNG images can be quite large. This post shows how to optimize PNG images instead of converting images to WebP as not everyone is ready to publish WebP images yet.
Installing optipng#
With optipng you can optimize PNG images. It is available in the repositories of most Linux distributions as shown below for Ubuntu and Debian.
$ sudo apt-get install optipng
On Fedora and CentOS you can install optipng
with the following command.
$ sudo dnf install optipng
Note
An alternative way is to install optipng-bin with npm as it the executable is part of the package/module.
$ npm install optipng
Optimize PNG images#
If we take the images same images from a previous post How to Convert Images to WebP we can optimize them with optipng
as shown below and see how much space we can save.
$ ls -l add-issues-to-projects-*
-rw-r--r--. 1 user01 user01 40653 Mar 22 10:48 add-issues-to-projects-1.png
-rw-r--r--. 1 user01 user01 14164 Mar 22 10:49 add-issues-to-projects-1.webp
-rw-r--r--. 1 user01 user01 94538 Mar 22 10:48 add-issues-to-projects-2.png
-rw-r--r--. 1 user01 user01 34864 Mar 22 10:49 add-issues-to-projects-2.webp
The command optipng
is used to optimize PNG images. It takes the name of the PNG image as an argument. The -o
option can be used to set the optimization level. The default is 2
. The higher the optimization level the more time it takes to optimize the image. The same goes for additional filter types, but lets start with the default options.
$ optipng add-issues-to-projects-*.png
** Processing: add-issues-to-projects-1.png
983x305 pixels, 4x8 bits/pixel, RGB+alpha
Reducing image to 3x8 bits/pixel, RGB
Input IDAT size = 40438 bytes
Input file size = 40653 bytes
Trying:
zc = 9 zm = 8 zs = 0 f = 0 IDAT size = 27158
Selecting parameters:
zc = 9 zm = 8 zs = 0 f = 0 IDAT size = 27158
Output IDAT size = 27158 bytes (13280 bytes decrease)
Output file size = 27324 bytes (13329 bytes = 32.79% decrease)
* Processing: add-issues-to-projects-2.png
983x735 pixels, 4x8 bits/pixel, RGB+alpha
Reducing image to 3x8 bits/pixel, RGB
Input IDAT size = 94239 bytes
Input file size = 94538 bytes
Trying:
zc = 9 zm = 8 zs = 0 f = 0 IDAT size = 64324
Selecting parameters:
zc = 9 zm = 8 zs = 0 f = 0 IDAT size = 64324
Output IDAT size = 64324 bytes (29915 bytes decrease)
Output file size = 64490 bytes (30048 bytes = 31.78% decrease)
After optimization we can see that the PNG images are smaller than before and the WebP images are still smaller, but the 30% decrease in size is still significant.
$ ls -l add-issues-to-projects-*
-rw-r--r--. 1 user01 user01 27324 Mar 26 10:48 add-issues-to-projects-1.png
-rw-r--r--. 1 user01 user01 14164 Mar 22 10:49 add-issues-to-projects-1.webp
-rw-r--r--. 1 user01 user01 64490 Mar 26 10:48 add-issues-to-projects-2.png
-rw-r--r--. 1 user01 user01 34864 Mar 22 10:49 add-issues-to-projects-2.webp
Note
The command optipng
has other options like -strip all
and -fix
. The -strip all
option can be used to remove all metadata from the image. The -fix
option can be used to fix some errors in the image. The -quiet
option can be used to suppress the output.
Converting PNG images to WebP#
In previous post How to Convert Images to WebP the PNG images were converted to WebP images with the command cwebp
. But can optimized PNG images be converted to WebP images with cwebp
and have a differen size. They can still be converted, but the file size doesn’t change.
$ ls -l add-issues-to-projects-*
-rw-r--r--. 1 user01 user01 27324 Mar 26 10:48 add-issues-to-projects-1.png
-rw-r--r--. 1 user01 user01 14164 Mar 26 10:49 add-issues-to-projects-1.webp
-rw-r--r--. 1 user01 user01 64490 Mar 26 10:48 add-issues-to-projects-2.png
-rw-r--r--. 1 user01 user01 34864 Mar 26 10:49 add-issues-to-projects-2.webp
The problem here is that optimized images are already compressed and the compression algorithm used by cwebp
is not able to compress the image further as there is no more data to compress. The only way to reduce the file size is to use a different compression algorithm, but there is a limit to how much the file size can be reduced.
Run optipng with GitHub Actions#
Using the command optipng
to optimize PNG images is easy, but it is not very convenient to run it on a local machine as it doesn’t garantee that the images are optimized. It is better to run it on a CI server like GitHub Actions. The following example shows how to run optipng
on GitHub Actions before pushing it to a content delivery network (CDN).
---
name: CI
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
optipng:
name: Optimize and push PNG images
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Optimize PNG images
uses: actions/setup-node@v3
with:
node-version: latest
- name: Optimize PNG images
run: |
npm install optipng-bin
npx optipng `git ls-files *\.png`
- name: Pushing assets to CDN
run: |
echo "Do something with the optimized images"