Lymphatus / caesium-image-compressor

Caesium is an image compression software that helps you store, send and share digital pictures, supporting JPG, PNG, WebP and TIFF formats. You can quickly reduce the file size (and resolution, if you want) by preserving the overall quality of the image.
https://saerasoft.com/caesium
GNU General Public License v3.0
3.56k stars 213 forks source link

Process Inquiry: WebP Conversion Behavior/Options #196

Open Saijin-Naib opened 1 year ago

Saijin-Naib commented 1 year ago

I am just settling on WebP transcoding for my entire picture library to net a significant filesize savings while minimizing any perceptual loss. I've been trying to hack together some ash script to handle this, but I'm not getting anywhere. Caesium has been my go-to lossless compression tool for a long time now, so I was super-excited to see it now has format transcode capability!

My question is this:
When converting to the WebP format, what behavior does Casesium have? Does it use cwebp internally, and if so, what options does it pass?

This is what I use for single-file conversions currently:

cwebp -q 90 -m 6 -sharp_yuv -pass 10 -mt -alpha_filter best -hint photo -metadata all -af -pre 2 -v -progress inputfile.extension -o outputfile.webp

Explanation:

Lymphatus commented 1 year ago

It really depends on the input image. If it is any other format than WebP, it uses the Qt internal QImageWriter to get the WebP. Thenpresses it further using the webp rust library. Here the references:

Saijin-Naib commented 1 year ago

Looks like default options all the way through... Hmm, not what I'm after, unfortunately.

Lymphatus commented 1 year ago

Conversion is not the primary goal of Caesium and just shipped with the 2.3.0 version, so it's very rough. I'd love to fine tune it more, but right now it's not top priority. But I will keep into consideration the parameters you described for future developments.

Saijin-Naib commented 1 year ago

Makes total sense, and even XNConvert doesn't Expose any of those options either, so I certainly don't mean to sound like I'm criticizing Caesium here.

Lymphatus commented 1 year ago

Absolutely not. Yours is a good feedback and a starting point for me to start digging deeper into aspects of the app that are still a bit rough. I'm just sad sometimes I cannot investigate further due to lack of time/resources. Keep up with feedbacks like that, they are helpful.

Saijin-Naib commented 1 year ago

226 might be related to not passing the metadata all flag, or equivalent.

Lymphatus commented 9 months ago

So I have an update on this actually. I need some testing, but seems I could be able to support most (if not all) of the options you mentioned. The only issue for now that they won't work while converting from a non-webp to webp, because the conversion is made by the Qt framework. But from WebP to WebP I think it could be possible.

There are a few issues and a bit of work to do if I also want to support converting. I will go into further details if you are interested, because it can be a little bit technical.

Saijin-Naib commented 9 months ago

Yeah, absolutely interested. What would you need from me?

Lymphatus commented 9 months ago

I'm absolutely no expert on that kind of options, so I might need so time and help understand what they really do and how they behave.

The Rust WebP library that Caesium uses (technically is used by libcaesium and the GUI integrates it) now can support all these options. If you have a reference or resource on what all those do it would help a lot.

About the specific Caesium issue: right now libcaesium does not support converting from/to different formats, it's a feature for the GUI version only. That means that when converting from (for example) JPG to WebP, the file is converted by the Qt Framework, which does not support any of those options, and then the file is compressed further by libcaesium, supporting the advanced options. What are the results using this process compared to directly converting using the WebP core library? I'd expect worst results, in terms of performance and quality.

The perfect scenario would be enhancing libcaesium to natively support converting from/to formats. Which will achieve the best results of course, but it's a lot more work heavy.

It's a bit complicated to explain, if something is not clear please tell me.

Saijin-Naib commented 9 months ago

Sounds good!

I got my info from the Google developer documentation for WebP.

Ah, okay yeah, I can see how that process could lead to generational loss and longer convert times.

Saijin-Naib commented 7 months ago

Here is the cwebp documentation that has a bit more detail about each flag:
https://developers.google.com/speed/webp/docs/cwebp

What would you need as next steps from me? Do you have a canonical test dataset you would like compressed with various settings?

Lymphatus commented 7 months ago

Sorry, didn't have too much time to dedicate to this issue. I'm planning to release a couple of feature for the next version and then focus on this one.

The perfect scenario would be enhancing libcaesium to natively support converting from/to formats. Which will achieve the best results of course, but it's a lot more work heavy.

This is the focal point and I must do it before supporting advanced flags for WebP. Also I'm introducing TIFF support and some more options for PNG and the interface is becoming a little clunky and that's something to consider.

Saijin-Naib commented 7 months ago

My hope was to isolate a set of best-quality parameters so no more UI bits need exposed.

The one that may need manual intervention, unless we do some really quick image content analysis, is hint, for tuning compression.

https://www.endpointdev.com/blog/2022/02/webp-heif-avif-jpegxl/

It might be easy to turn graph on for images with small color palettes, but no idea how to choose photo or picture, or if we even need to bother with hint 🤷

Saijin-Naib commented 3 months ago

My hope was to isolate a set of best-quality parameters so no more UI bits need exposed.

The one that may need manual intervention, unless we do some really quick image content analysis, is hint, for tuning compression.

https://www.endpointdev.com/blog/2022/02/webp-heif-avif-jpegxl/

It might be easy to turn graph on for images with small color palettes, but no idea how to choose photo or picture, or if we even need to bother with hint 🤷

Thinking about this more, maybe we could do a really quick on-the-fly compression test using all three of graph/photo/picture on a really small downsampled version of the input image and see which doesn't make it larger than the input image, and maybe using #262 we pick which one is closest to the input image (least change), to completely automate choosing which optimizer profile to apply.

maryla-uc commented 2 months ago

The -hint flag does almost nothing, you should ignore it. There is also a similar flag called -preset that can take the values [default, photo, picture, drawing, icon, text] You can see here that it changes a bunch of settings (which can all be tuned separately through flags). This one might affect the output more but it can also safely be left to "default".

Lymphatus commented 2 months ago

I was thinking about exposing the preset option because it's the most "user friendly" of all of them. A lot of users probably don't care too much about those fine tuning, but having some level of control can be nice.

Also having that many option would clutter the UI so much that would probably need a whole overhaul.

Anyway, I'm doing some tests with those options, let you know.