英文:
PIL not saving animated files as animated .webp
问题
这是一个函数的一部分,它可以正常工作,并且会在控制台打印出'saving as animated image'
。然而,保存的图像是静态的,不是动画的(尽管它是.webp格式的)。
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', ["您需要增强的个人资料高级功能才能上传动画头像。"])
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', ["出现了一些问题,开发人员已经收到通知。"])
response.status = status.HTTP_400_BAD_REQUEST
return response
英文:
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
答案1
得分: 1
所以这段代码实际上有两个问题。
- 从某种意义上说,代码是正确的。我在抱怨我无法保存1帧的问题。但我有权抱怨,因为事实上我上传了一个gif文件,并且如第2点所解释的那样,我确信我正在处理一个动画文件。问题出在哪里?就在开头。
img = ImageOps.exif_transpose(img)
不支持多于1帧的图像。它可以工作,但只会对第一帧应用更改,而忽略其他帧。所以实际上,我试图存储1帧,以为我仍然拥有原始的gif文件。 is_animated_image
实际上计算的是1帧或多帧,而不是多于1帧。所以如果我没有如此确信这个函数只在有多于1帧时返回True,我可能早就发现了问题。
感谢@Mark Setchel让我更深入地研究我的代码。
英文:
So this code actually contained 2 issues.
- The code in a way was fine. I was yelling about how I couldn't save 1 frame. But I had all rights to yell because I did in fact upload a gif and as explained in point 2, I was convinced I was working with an animated file. Where did it go wrong? Right at the beginning.
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. - The
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论