ajslater / picopt

A multi format lossless image optimizer that uses external tools

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support oxipng

veikk0 opened this issue · comments

commented

oxipng is a PNG optimizer written in Rust that began as a rewrite of optipng during the years when it was thought dead. Its CLI syntax is very similar and from what I've seen, it's almost a drop-in replacement and just better than optipng in every way.

The biggest improvement is in the speed. Below are some quick tests on a set of 40 PNG frames extracted from a video, with execution time measured using /usr/bin/time -p. optipng is version 0.7.7 and oxipng is 8.0.0.

optipng -o1: 32.8% size reduction, time:

real 158.23
user 157.75
sys 0.32

oxipng -o1: 38.4% size reduction, time:

real 66.70
user 65.69
sys 0.95

optipng -o2: 32.7% size reduction, time:

real 314.14
user 313.22
sys 0.35

oxipng -o2: 39.3% size reduction, time:

real 117.64
user 137.36
sys 1.02

optipng -o3: 32.9% size reduction, time:

real 633.62
user 632.56
sys 0.44

oxipng -o3: 41.2% size reduction, time:

real 204.86
user 615.39
sys 3.33

(I couldn't be asked to test further, since optipng's -o3 is already annoyingly slow.)

So with its fastest setting, oxipng is 2.4x faster than optipng and achieves better compression than optipng can get at even -o3. And as can be seen from the real vs user/sys time, oxipng has multithreading, though it only really seems to be effective at some -o levels. This can also be limited with --threads.

oxipng can also use Zopfli (invoked with -Z), but that's extremely slow and more of a "for fun" / out of interest option rather than something practical for anything but low resolution files.

picopt 4.0.0 includes pyoxipng. You don't even need to download oxipng as an external library! You may squeeze a couple extra bytes out of your pngs (not much really) by downloading pngout which will run after oxipng if it is available.

oxipng is currently run with zopfli using the default 15 cycles. idk this is a bit slow, so if there are complaints i might drop the cycle count. For web applications you should really convert pngs to lossless webp, but there do remain png applications that are not practical to convert.

picopt no longer uses optipng.

Nice! Not needing to install it separately is an especially nice touch.

I definitely think using Zopfli by default is excessive. It's probably fine for small PNG logos/icons and such used on the web, but it takes a lifetime for anything on the megapixel scale.

I just did a test on 54 ~0.7 megapixel manga pages using oxipng 9.0.0 while measuring CPU time with /usr/bin/time -p:

o1 o2 o3 Z
CPU time 18.52 29.8 108.57 2227.89
bytes saved 996 1068 1084 1132

Granted, this is just a specific use case and a fairly small sample size. Smaller PNGs, files from different sources etc. would yield different results, so YMMV. But with most files I work with I've come to a similar conclusion; with the latest version of oxipng, spending 120x CPU time vs. -o1 isn't worth it for a single-digit increase in compression.

I usually just use -o1. This latest release of oxipng made -o1 the sweet spot IMO.

Maybe having a max option like oxipng itself would be a good idea? And maybe some logic that chooses the o level based on image size. Running Zopfli on multi-megapixel images is not a great idea if you want the process to finish withing a reasonable time frame.

Edit: It also bears mentioning that the Zopfli compression in oxipng seems to be single-threaded, whereas the regular compression modes seem to be at least somewhat multi-threaded. So if you have a single large PNG in your batch of images, using Zopfli might stretch the process to minutes, hours, or even longer depending on the size.

version 4.0.1 reduces the overzealous png optimization to O3 without Zopfli. Thanks for mentioning it here.