Selectively Compressed Images - A Hybrid Format
I have a screenshot of my phone's screen. It shows an app's user interface and a photo in the middle. Something like this:
If I set the compression to be lossy - the photo looks good but the UI looks bad. If I set the compression to be lossless - the UI looks good but the filesize is huge.
Is there a way to selectively compress different parts of an image? I know WebP and AVIF are pretty magical but, as I understand it, the whole image is compressed with the same algorithm and the same settings.
There are two ways to do this. The impossible way and the cheating way.
Selective Compression
In theory it should be possible to tell an image format to compress some chunks of an image with a different compression algorithm.
And yet... none of the documentation I've found shows that's possible.
GiMP's native XCF and Photoshop's PSD files work; they store different layers each of which can have a different filetype. I understand that TIFF and .djvu also have that capability.
But those sorts of files don't display in web browsers.
So...
Let's Cheat!
It's possible to use an SVG to embed multiple images of different formats. SVG is used as, effectively, a layout engine.
The syntax is relatively straightforward:
XML<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1080 512">
<image width="1080" height="512" x="0" y="0"
xlink:href="data:image/jpeg;base64,..........."
/>
<image width="1080" height="512" x="0" y="0"
xlink:href="data:image/png;base64,..........."
/>
</svg>
That draws the JPG then draws the PNG on top of it. If the PNG has a transparent section, the JPG will show through. The JPG can be set to as low a quality as you like and the PNG remains lossless.
Here's what it looks like - click for full size:
Embedded images are Base 64 encoded, which does lose some of the compression advantages. But, overall, it's smaller than a full PNG and better quality than a full JPG.
Look, if it's stupid but it works it's not stupid.
But surely there must be a way of doing this natively?
David Underdown said on digipres.club:
@Edent JPEG2000 has the concept of Region(s) of Interest which goes somewhat in this direction https://www.sciencedirect.com/science/article/abs/pii/S0923596501000261 (not sure how widely it's implemented in the available tools however)
Chris says:
Came here to say exactly the same thing about JPEG2000 that @DavidUnderdown just did. But I wanted to add that the SVG as a layout engine idea is one of those brainwaves that should be blindingly obvious that I’ve never thought of trying before. But I will now. Thanks for posting this.
Andrea Grandi 🦕 said on mastodon.social:
@Edent I'm just a jealous guy (of your vinyls collection) 😅
blankie says:
Shouldn't the mime type for the JPG be image/jpeg? librsvg doesn't render the JPG part since it doesn't recognize image/jpg: https://gitlab.gnome.org/GNOME/librsvg/-/issues/389
@edent says:
You are correct! But, as ever, Postel's Law applies 🙂
zeroheure says:
You can also try to less or more compress regions in JPEG. In the glory old days of the internet, there were several softwares to do that.
@edent says:
JPEG is lossy - so would probably destroy the data encoded within the image. But if you can find a way to do it, please let me know!
More comments on Mastodon.