-
-
Notifications
You must be signed in to change notification settings - Fork 646
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
cgifsave: avoid size issue #2628
Conversation
avoid size issue by restoring the original transparency setting after quantization/dithering
Further improvements / additional notes: Command used:
I thought about taking the human perception of colors into account e.g. by weighting the red/green/blue channels differently or getting luminance into play. Such a modification should reduce the visibility of possible artifacts. But maybe that is something more for a follow-up PR, as the quality seems to be quite good already (2576#comment). |
Yes, that's a good idea. CIELAB is the simplest perceptually uniform colour space (mostly uniform anyway!) so I would use that. https://en.wikipedia.org/wiki/CIELAB_color_space#From_CIEXYZ_to_CIELAB sRGB -> XYZ is this: https://en.wikipedia.org/wiki/SRGB#From_CIE_XYZ_to_sRGB You only need 8 bit data and you don't care about small errors, so you can cut a lot of corners. You'll find you end up with something like:
Not too painful. libvips has a fairly fast srgb -> lab path, but it'd probably be simpler to code your own. You could use the libvips one to check your implementation, of course. |
Thanks @jcupitt for this very detailed explanation! |
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.
The C programmer in me couldn't resist making some unnecessary optimisation, of course :( gif write is about 10% faster on my PC with the suggested changes. Maybe not a useful amount.
I noticed some small layout and naming things too.
no need to 0 initialize at this point
Makes all perfect sense. Thanks! |
The PR depends on cgif v0.2.0. |
510b6ef
to
ef625ba
Compare
avoid size issue by restoring the original transparency setting after quantization/dithering
no need to 0 initialize at this point
…into cgifsave-fix-size
Ok, let's merge! Nice work @dloebl |
also note in changelog and revise layout for 80 columns see #2628
Avoid size issues when resizing GIF animations with a static background. The trick is to restore the original transparency setting after quantization and dithering.
Background: Keeping many pixels at the transparency index can reduce the size a lot and is the reason why the original animations in (#2576) are quite small in terms of bytes despite their huge width/height. The current resizing and subsequent color quantization method puts the focus on image quality but can make this transparency optimization less effective.
The suggested fix depends on dloebl/cgif#38 and cgif 0.2.0 to be released:
Results:
$ vipsthumbnail --size 200 city.gif[n=-1] -o vips_city.gif
$ vipsthumbnail --size 1400 watch.gif[n=-1] -o vips_watch.gif
$ du -h vips_*
2.2M vips_city.gif
812K vips_watch.gif
The size is still larger than before, as the transparency setting is changed by the resizing. However, the two animations are probably extreme cases and the size problem is mitigated quite a bit with this change.
I've visualized the transparency setting for the resized city GIF and the original (green means that a pixel is identical to the frame before):
Resized:
Original:
One can see some "kernels" (in the resized image). I guess these come from the interpolation method and illustrate where the remaining increase in size comes from. To further improve the size it could be interesting to have a "transparency-friendly" resize method (which keeps identical areas identical). For instance, nearest-neighbor resizing would be "transparency-friendly" but is of course not ideal in terms of quality. An alternative would be to determine transparent areas in a lossy way in cgifsave (I think @jcupitt once mentioned such a low-pass filter). So the problem is finding the right balance between quality and size.
Please let me know if there are changes required on this PR.