-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add modified zeng palette sorting method #602
Conversation
I actually will tidy this up a bit (it's based on C code from libwebp), so will convert to draft while I do that... |
@andrews05 - nice! I'm working on an image set, where I have been brute-forcing the palette order. I'd been keen to test this method too! One thing I've noticed, is occasionally the existing palette is already the most optimal. Ideally this should be evaluated too (i.e. a 'no-sort' if the starting image is indexed). This will also help if |
Brute-forcing, like all possible permutations? Wow, that's dedication 😅. How are you doing that? Oxipng does evaluate the existing palette too. You can disable all palette sorting if you need to with |
I have also been brute-forcing a bunch of OxiPNG permutations (including two |
@Winterhuman nice! I still think it's odd that you're using pngquant in a lossless mode though, which is not what it was built for. You'd be better off swapping it for one or more other lossless optimisers, such as: PNGOUT, AdvPNG, PNGCrush, ECT, OptiPNG, PngOptimizer, pngwolf etc. Piping oxipng output into ECT, for instance, could be quite effective as it has a more advanced deflate compressor. Existing png multitools include ImageOptim, FileOptimizer, and @ace-dent's pngslim. |
Right, I've updated with much cleaner, less C-looking code. I've also made a change to the first colour to improve savings even more (see updated description at top). |
@andrews05 - quick reply while our time zones are in sync (!) ~ My working theory was that popular colour made sense at index Edit: Ahh... I think I have some idea. But would love to hear your theories / insight. :-) |
Yeah you're right, the most popular colour and most popular edge colour are usually the same, and even when they aren't the choice between the two often doesn't make much difference. The difference is likely more around situations where the "most popular" isn't actually that popular and putting it first may actually be detrimental. This could happen e.g. in high-detail or photographic material where there are many colours but none that are particularly prominent. These would also likely be image types where the luma sort would not be effective, which is why it may better to retain the edge colour there. The increased diversity by doing different things in different sort methods may also be beneficial. I haven't tried the 20% threshold with the edge colour yet. I don't anticipate that would be effective, but can certainly try. Of course, I've spent much time already tweaking and experimenting with various things and I have to stop at some point 😄 I don't have the image set with me right now but I can post some samples later. |
@andrews05 I've spent a few hours thinking about this... Corpus is going to have a big effect here. For small pixel art / icons, nearly always have filter 0. Larger screenshots often favour more complex filters (mix of all).
I do think this is worth testing 🙏🏻 ... BTW, how did you arrive at 20%? |
I've made some more tweaks: Lowered the threshold to 15%, and removed the final rotation of the array in the mzeng method. Saved around 2k total across both sets. @ace-dent I tried the 20% with the edge colour - it made negligible difference (regressed a tiny amount). |
@andrews05 - Thanks! Will look over the image with a coffee :-) [Update: Wow! That's a lotta pixels to optimize!]
I'm still thinking about this heuristic... I assume we cannot know the row filters, at the stage we are doing the palette sort? (I appreciate they may strongly interrelate, so sanely we might pick which to optimise for first). |
Feature request: is it possible with |
@ace-dent Correct, we don't know the filters. The filter most commonly ends up being either None or one of the heuristic ones. Rarely is it exclusively one of the other delta filters, so trying to optimise for anything other than 0 is probably not helpful. And yeah, it would be nice to have more info on those eval lines which are currently identical. I'll see if I can do something about that after this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, I agree that any logging changes can be done in another PR. Great work! ❤️
Hi @andrews05 - sorry to necropost... I have attached a small corpus of indexed images (GPL licensed), for future algo tuning. I can provide examples of winning and losing paletted images too, if it helps? Many thanks. |
@ace-dent Nice. Yeah, some examples of losing ones could be interesting, along with what algorithm it lost to and by how much. |
@andrews05 - not sure when I will be able to do forensics on the images, so have attached them as is. Will try to review in future. |
This PR adds the modified zeng ("mzeng") palette sorting method, in addition to the existing luma and battiato methods. Speed is very similar to the battiato method with slightly better results on average.
Resulting sizes from two different image sets (all indexed or able to be indexed):
Additionally, I've added a new "first colour" heuristic for both the mzeng and battiato methods: We use the most popular colour overall, but only if it covers at least 15% of the image. This provided 13k savings on Set 2 vs the edge colour heuristic (which is still used in the luma sort).