我有一个gif
,我想用pillow
调整它的大小,这样它的大小就会减小。gif
的当前大小为2MB
我正在努力
调整其大小,使其高度/宽度更小
降低其质量
对于JPEG,下面的代码通常足以使大图像的大小急剧减小
from PIL import Image
im = Image.open("my_picture.jpg")
im = im.resize((im.size[0] // 2, im.size[1] // 2), Image.ANTIALIAS) # decreases width and height of the image
im.save("out.jpg", optimize=True, quality=85) # decreases its quality
不过,对于GIF,它似乎不起作用。下面的代码甚至使out.gif
比初始gif更大:
im = Image.open("my_gif.gif")
im.seek(im.tell() + 1) # loads all frames
im.save("out.gif", save_all=True, optimize=True, quality=10) # should decrease its quality
print(os.stat("my_gif.gif").st_size) # 2096558 bytes / roughly 2MB
print(os.stat("out.gif").st_size) # 7536404 bytes / roughly 7.5MB
如果添加以下行,则仅保存GIF的第一帧,而不是其所有帧
im = im.resize((im.size[0] // 2, im.size[1] // 2), Image.ANTIALIAS) # should decrease its size
我一直在考虑对im.seek()
或im.tell()
调用resize()
,但这两个方法都不返回图像对象,因此我无法对其输出调用resize()
你知道我如何使用枕头来减少GIF的大小,同时保留所有的框架吗
[编辑]部分解决方案:
在Old Bear's response之后,我做了以下更改:
我正在使用BigglesZX's script提取所有帧。值得注意的是,这是一个Python2脚本,我的项目是用Python3编写的(我最初确实提到了这个细节,但它被Stack Overflow社区编辑掉了)。运行2to3 -w gifextract.py
使该脚本与Python 3兼容
我已经分别调整了每个帧的大小:frame.resize((frame.size[0] // 2, frame.size[1] // 2), Image.ANTIALIAS)
我一直在一起保存所有帧:img.save("out.gif", save_all=True, optimize=True)
新的gif现在已保存并工作,但存在两个主要问题:
我不确定resize方法是否有效,因为out.gif
仍然是7.5MB。最初的gif是2MB
gif速度增加,gif不会循环。它在第一次运行后停止
例如:
原始gifmy_gif.gif
:
Gif处理后(out.gif
)https://i.imgur.com/zDO4cE4.mp4(我无法将其添加到堆栈溢出)。Imgur使其速度变慢(并将其转换为mp4)。当我从电脑中打开gif文件时,整个gif大约持续1.5秒
我正在使用下面的函数来调整和裁剪图像,包括动画图像(GIF、WEBP)。简单地说,我们需要在GIF或WEBP中迭代每个帧
使用BigglesZX's script,我创建了一个新脚本,它使用枕头调整GIF的大小
原始GIF(2.1MB):
调整大小后输出GIF(1.7 MB):
我已保存脚本here。它使用枕头的
thumbnail
方法而不是resize
方法,因为我发现resize
方法不起作用这是不完美的,所以请随意叉和改善它。以下是一些尚未解决的问题:
stack.imgur
时,它无法正确显示。只显示了第一帧(您可以看到它here)李>完整代码(如果删除上述要点):
根据Pillow 4.0x,Image.resize功能仅在单个图像/帧上工作
为了达到您想要的效果,我相信您必须首先从.gif文件中提取每一帧,一次调整每一帧的大小,然后重新组装它们
要完成第一步,似乎需要注意一些细节。例如,每个gif帧是否使用本地调色板或全局调色板应用于所有帧,以及gif是否使用完整或部分帧替换每个图像BigglesZX开发了一个脚本来解决这些问题,同时从gif文件中提取每一帧,以便充分利用这一点
接下来,您必须编写脚本来调整每个提取帧的大小,并使用PIL.Image.resize()和PIL.Image.save()将它们全部组装为一个新的.gif文件
我注意到你写了“
im.seek(im.tell() + 1) # load all frames
”。我认为这是不正确的。相反,它用于在.gif文件的帧之间递增。我注意到您在.gif文件的保存函数中使用了quality=10。我没有在PIL documentation中找到这一点。通过阅读以下link可以了解BiggleZX脚本中提到的tile属性的更多信息相关问题 更多 >
编程相关推荐