This is a part of a function, it all works and 'saving as animated image'
gets printed out to console. However, the saved image is a still one. It is not animated (it is .webp though).
try:
with Image.open(avatar) as img:
img = ImageOps.exif_transpose(img)
if is_animated_image(img) and not permissions.Flags.enhanced_profile in user_permissions:
response.add_errors('avatar', ["You need the enhanced profile premium feature to upload animated avatars."])
response.status = status.HTTP_400_BAD_REQUEST
return response
width, height = img.size
if width != height:
print('resize_avatar')
return resize_avatar(img, is_animated_image(img), attachment_name)
if is_animated_image(img):
print('saving as animated image')
frames = []
for frame in ImageSequence.Iterator(img):
frames.append(frame)
frames[0].save(
f'{config.media_source}avatars/{attachment_name}',
format='webp',
save_all=True,
append_images=frames[:1],
loop=0,
)
else:
img.save(f'{config.media_source}avatars/{attachment_name}', format='webp', save_all=True)
response.status = status.HTTP_200_OK
response.data = {'attachment_name' : attachment_name}
return response
except Exception as e:
functions.log_error("UPLOAD_AVATAR_ERROR", str(e))
response.add_errors('avatar', ["Something went wrong, the developers have been notified."])
response.status = status.HTTP_400_BAD_REQUEST
return response
So this code actually contained 2 issues.
img = ImageOps.exif_transpose(img)
does not support images with more than 1 frame. It works, but would only apply changes to the first frame and forget about the other frames. So in fact I was trying to store 1 frame thinking I still had my original gif.is_animated_image
actually counted for 1 or more and not more than 1 frames. So I could have figured out earlier there was an issue if I wasn't so convinced this function only returned True when we had more than 1 frame.Thanks @Mark Setchel for making me deep dive more in my code.