Can Spectacle Optimize PNG files?

Using e.g. pngquant or optipng the reduction in filesize is immense, the end result is usually 3-4 times smaller and (almost always) indistinguishable from the original.

I have long automated optimizing PNG screenshots immediately after taking them, but my recent switch to KDE&wayland is throwing up hurdles here:

I cannot easily switch to a different tool, and I cannot easily script Spectacle to take a screenshot, run pngquant on it, then send a notification and copy the path to the clipboard. Because Spectacle fully saves a screenshot to disk but still takes several seconds to exit after that, resp. return the command prompt (a solution to that would also be welcome).

I was thinking the in-built edit/annotation could be (ab)used to run a command, but don’t see how. But maybe I can use a simple pngquant-script to act as the annotation tool? Spitballing…

TIA!

Spectacle has the pieces for this. A shortcut can call a wrapper like:

out="$HOME/Pictures/Screenshots/$(date +%F-%H%M%S).png"
spectacle -b -n -o "$out"
pngquant --force --ext .png --quality=65-90 "$out"

-b keeps the GUI out, -n drops the notification, -o picks the file. If ur Wayland build keeps Spectacle open after saving, watch the screenshot dir with inotifywait -e close_write and run pngquant on the new .png rather than waiting on Spectacle. -C copies the saved path if u need clipboard too.

Depending on what you plan on doing with your screenshots afterwards, you might also consider saving them as lossless jxl (JpegXL), which should end up even smaller than even well optimized png. Edit: just now reading that pngquant somehow makes png compression lossy, which is kind of a new concept to me. But if quality loss is acceptable, jxl should end up even better in comparison.

Not exactly. The conversion is lossy, the resulting file isn’t.

Well, that’s really just semantics, isn’t it? I’d argue a “file” is always lossless, because you can copy it around as often as you want without its data changing. On the other hand, when you’re losing image data on conversion you can’t call PNG a lossless format anymore and for now I don’t really see the point compared to more modern formats, but I’ll have to look into it and try out what it really does for myself, I guess.

You can run a separate script to watch the screenshot dir, and compress incoming files:

cd ~/Pictures/Screenshots
watchexec -- find . -type f -name \'*.png\' ! -name \'*-compressed.png\' -exec pngquant --ext \'-compressed.png\' \'{}\' \\\; -exec rm \'{}\' \\\;

What I meant is that the result is still just a normal PNG file, which is defined as lossless.

You probably don’t want to use it for your amazing 24MB 4k wallpaper, but it’s great for sharing screenshots. Tiny files, much crispier than jay-peck.

Why not use lossless WebP? It’s not well documented, but if you set quality to 100 with WebP selected, you get a lossless WebP (the behavior comes from QImageWriter).

The sample size I have is only 2 articles, but it looks like lossless WebP is generally better than optimized PNG.

I’m not sure I want to have custom image encoding logic beyond what QImageWriter supports anyway.

Can confirm. WebP usually reduces file size by 30-60% even at a quality of 100. Reducing the quality to just 80% gives an even more drastic reduction in file size ranging from 60-97% smaller files.

A popular scheme found in other screenshot tools is to allow piping the picture to an external program. Not necessarily compressor. Maybe annotator, send to phone, etc.

Given that screenshots aren’t artistic paintings, using pngquant (converting to 256 colours and saving about 70% space in the process) is perfect for capturing the UI.

I’d look to call spectacle -b -n -o then (wait for the file to settle) call up pngquant, move it to screenshots and copy the path with a notification.

Is it not possible to do that with formats other than PNG?

Thank you, this is definitely better… almost perfect:

A PNG screenshot is 170kB and optimises to 61.5kB, a (otherwise identical) lossless webp screenshot is 83kB, so not better in terms of filesize.

This is of course much better than unoptimized PNG and would not require any additional action.

Spectacle does not write the resulting image to stdout btw.

I have decided to use flameshot instead, which can dump raw PNG (their words not mine) to stdout:

flameshot gui -r | pngquant - -o \
~/Pictures/Screenshots/scrsh_$(date +%Y%m%d_%H%M%S).png

All is good.