Optimizing a bunch of images in a directory

I found these commands here coincidentally on a pull request at Github. I found them quite handy ;-)

1find . -type f -name "*.png"  -print0 | xargs -0 -I {} optipng -nb -nc "{}"
2find . -type f -name "*.png"  -print0 | xargs -0 -I {} advpng -z4 "{}"
3find . -type f -name "*.png"  -print0 | xargs -0 -I {} pngcrush -rem gAMA -rem alla -rem cHRM -rem iCCP -rem sRGB -rem time -ow "{}"

Quickly optimizing only one image

I’ve set up a function in my .zaliases file for this to be done on a single image aswell:

1function opti() {
2  optipng -nb -nc "$*";
3  advpng -z4 "$*";
4  pngcrush -rem gAMA -rem alla -rem cHRM -rem iCCP -rem sRGB -rem time -ow "$*";
5}

To run all three commands on a single image I just call it like that:

1opti image.png

That’s all the magic it needs.

Use jpegtran for JPG images

1jpegtran -copy none -optimize -progressive -outfile output.jpg input.jpg

Install these tools on your system

On debian or ubuntu

1sudo apt-get install optipng pngcrush advancecomp

On Arch based distros using pacman

1sudo pacman -S optipng pngcrush advancecomp

On macOS

1sudo port install optipng pngcrush advancecomp

or if you use homebrew

1brew install optipng pngcrush advancecomp

You may know other package managers commands, but I only use these.

An example

By filesize

The files taken from the snapshot tool on my macbook.

1 33K 00_locales.png
2 61K 01_control-software.png
3157K 02_mmdvmhost.png
4184K 03_general.png
5187K 04_dmrconfig.png
6 69K 05_exp_mmdvmhost-dmrnetwork.png
7212K 06_exp_dmrgw-dmrnetwork1.png
8236K 07_exp_dmrgw-dmrnetwork2.png

Three to four minutes later (all three commands):

1 17K 00_locales.png
2 33K 01_control-software.png
3 81K 02_mmdvmhost.png
4 98K 03_general.png
5 97K 04_dmrconfig.png
6 32K 05_exp_mmdvmhost-dmrnetwork.png
7127K 06_exp_dmrgw-dmrnetwork1.png
8144K 07_exp_dmrgw-dmrnetwork2.png

By view

1 25K opti_01.png
2 13K opti_02.png

Original image Optimized image

Do you see much difference?

Using this with the fish shell

I added this to my fishs configuration (when I used fish for a while).

 1# file: "~/.config/fish/functions/opti.fish"
 2function opti --description "Optimizes .png files"
 3    # Author: Dominic, OE7DRT <[email protected]>
 4    # 2021-04-17
 5    set -e missing
 6
 7    for program in optipng advpng pngcrush
 8        if \! command -v $program > /dev/null
 9            set -a missing $program
10            continue
11        end
12    end
13
14    if test -n "$missing"
15        echo "Could not find executables: $missing"
16        return 1
17    end
18
19    if test -z $argv[1]
20        echo "usage: opti <files...>"
21        return 1
22    end
23
24    set count (count $argv)
25
26    for i in (seq 1 $count)
27        if test ! -f $argv[$i]
28            echo "Could not read file $argv[$i]..."
29            continue
30        end
31
32        optipng -nb -nc "$argv[$i]";
33        advpng -z4 "$argv[$i]";
34        pngcrush -rem gAMA -rem alla -rem cHRM -rem iCCP -rem sRGB -rem time -ow "$argv[$i]";
35    end
36end

And I made one for the jpeg version too:

 1# file: "~/.config/fish/functions/jopti.fish"
 2function jopti --description "Optimizes .jpg files"
 3    # Author: Dominic, OE7DRT <[email protected]>
 4    # 2021-08-07
 5    set -e missing
 6
 7    for program in jpegtran
 8        if \! command -v $program > /dev/null
 9            set -a missing $program
10            continue
11        end
12    end
13
14    if test -n "$missing"
15        echo "Could not find executables: $missing"
16        return 1
17    end
18
19    if test -z $argv[1]
20        echo "usage: jopti <files...>"
21        return 1
22    end
23
24    set count (count $argv)
25
26    for i in (seq 1 $count)
27        if test ! -f $argv[$i]
28            echo "Could not read file $argv[$i]..."
29            continue
30        end
31
32        jpegtran -copy none -optimize -progressive -outfile "$argv[$i]" "$argv[$i]"
33    end
34end