Support for animated formats (gif/webp/apng)
A first draft. Test still passing, no new tests for the moment.
I don't think that a wrapper (processors leaving as is, abstract things away for processors) would be a good solution, as some processors could still not operate like this. For example, the autocrop would autocrop each frame individually, and if a processor creates a new Image(), and pastes the original into it, frames would still be lost - as the background processor does it.
With my proposal, animated GIF support would need to be supported by each processor individually. Most of the times, this would mean a simple usage of the new helper function instead of directly calling im.whatever().
Using
THUMBNAIL_IMAGE_SAVE_OPTIONS = {
"GIF": {"save_all": True},
}
THUMBNAIL_PRESERVE_EXTENSIONS = ("gif", )
And animated GIFs work (on my machine), hopefully animated WEBP would as well. A first feedback for the approach is very welcome.
I've had to add a BytesIO use, did not work otherwise. I've tried many things to treat the file in place, but it's not working till now...even asked on SO: https://stackoverflow.com/questions/78020254/python-pillow-treat-an-animated-gif-or-webp-in-place
Feedback welcome, I'm not so sure about not leaving open file pointers around?
...also, will remove _call_pil_method soon.
It has tests now, for all builtin processors. Though, it only tests if frames are preserved, and some of the basic functionalities (as resize/crop) - I'm afraid I don't fully understand all of the processors, and especially not all of the edge cases involved.
If the used BytesIO workaround is ok for @SmileyChris I think it could be merged?
...remaining to add: docs. Also, I would add save_all=True for all images with more than one frame, it would be better to support them without having to set/use THUMBNAIL_IMAGE_SAVE_OPTIONS.
...also, docs: how to make them work again?
@SmileyChris feedback welcome :) or maybe shall I reach out to @jrief ?
@benzkji Hi Ben, you're changing code and code-styling in the same pull request. This makes a review extremly difficult to understand. Can this be split into separate PRs?
And btw., I prefer single quotes for strings which are not read by humans, but this is my personal opinion.
@jrief Hi Jacob. Sorry, that slipped in, I probably had black active on save. Will try to revert these changes.
things remaining (code style is reverted):
- wether to enable "save_all" by default if multiple frames are detected?
- write docs
- test in real live (done that a few months before with django-filer, but it did not always work...), with webp, etc.
real world feedback with django-filer:
- animated png/gif/webp all work, when preserving their extensions and setting save options
- some animated gifs could not be saved as WEBP, because of a problem during saving the image in PIL.
- gif/webp>png is not preserving the animation
- but in general, gif>web and png>webp was working
- bigger images could block your server
Thinking about it, it would be nice if one could define if animations should be preserved, when using easy-thumbnails...not an "always on/off" solution, but rather some kind of crop=1 animated=1/0 ?! @jrief next step?!
if anyone interested:
PIL/WebPImagePlugin.py, line 199, in _save_all > not enough values to unpack (expected 3, got 0) is the error, when trying a special GIF (probably because of a reduced palette) to .webp.
but, without "save_all" enabled for everyone automatically, I guess this could be released as a beta, if no issues arise. People could check manually, with preserve extensions and save_all, if it works. hopefully no existing features would be broken, aka we have a testsuite - I don't know how extensive it is?!
@jrief done so (docs & changelog). BTW, do you know what must be done to get readthedocs up and running again? https://easy-thumbnails.readthedocs.io/en/latest/ is for 2.7, no word of SVG et al?
ah, shall I merge master into my branch? My current local tests are passing (without python3.7 ;), but that's not up to date at all.
thx. will check the testsuite.
@benzkji I assume that the local behavior of colorspace is different from what the tests on GitHub-Actions tell us. Any idea what could be the problem?
not yet. After the merge it fails localy on my machine as well.
test pass now. it is strange, though, it seems PIL eliminates empty frames. but also, my test PNG and WEBPs seem empty (when saving them out), but when using filer it works, and in tests it works as well, now. Looks like a "writing the tests is the hardest part" problem. I must say that I'm not really familiar with creating images from within PIL, so this could be the issue.