如何打开优化的 GIF 没有错误?
How to open optimized GIF without bugs?
所以这个 GIF 在打开之前看起来非常完美:
但是,当使用 Pillow 打开时使用
imageObject = Image.open(path.join(petGifs, f"{pokemonName}.gif"))
它出错了,添加了与源图像颜色相似的各种框。这是一个示例帧,但几乎每一帧都是不同的,并且它在不同的位置取决于 GIF:
唯一解决这个问题的方法是 ezgif 的取消优化选项(在他们的 optimize page 中找到)。但是,我需要在每个 GIF 上都这样做,而且有很多。
我需要一种批量取消优化的方法,或者一种在 Python(目前使用 Pillow)中打开 GIF 的新方法,这将解决这个问题。
您可以尝试使用:
from PIL import Image, ImageSequence
im = Image.open(f"{pokemonName}.gif")
index = 1
for frame in ImageSequence.Iterator(im):
frame.save("frame%d.png" % index)
index += 1
至少对于提取正确的单帧可能有一个解决方案。
所有帧(第一帧除外)的disposal
方法设置为2
,即“恢复为背景颜色”。
深入了解 Pillow 的源代码,您会找到相应的 line where the disposal method 2
is considered,并且在下文中,您会发现:
# by convention, attempt to use transparency first
color = (
frame_transparency
if frame_transparency is not None
else self.info.get("background", 0)
)
self.dispose = Image.core.fill("P", dispose_size, color)
如果您检查错误的框架,您会注意到不需要的框的这种深绿色位于调色板的位置 0
。因此,似乎选择了错误的颜色进行处理,因为 – 我还不知道为什么 – 选择了上面的 else
案例而不是使用透明度信息 – 本来就在那里!
所以,让我们重写可能有问题的东西:
from PIL import Image, ImageSequence
# Open GIF
gif = Image.open('223vK.gif')
# Initialize list of extracted frames
frames = []
for frame in ImageSequence.Iterator(gif):
# If dispose is set, and color is set to 0, use transparency information
if frame.dispose is not None and frame.dispose[0] == 0:
frame.dispose = Image.core.fill('P', frame.dispose.size,
frame.info['transparency'])
# Convert frame to RGBA
frames.append(frame.convert('RGBA'))
# Visualization overhead
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 8))
for i, f in enumerate(frames, start=1):
plt.subplot(8, 8, i), plt.imshow(f), plt.axis('off')
plt.tight_layout(), plt.show()
提取的帧如下所示:
我觉得不错。
如果偶然将透明度信息实际设置为 0
,则此处不应造成任何伤害,因为我们(重新)设置了仍然正确的透明度信息。
我不知道,(重新)保存到 GIF 是否可行,因为帧现在处于 RGBA
模式,从那里保存到 GIF 也很棘手。
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.19041-SP0
Python: 3.9.1
PyCharm: 2021.1.3
Matplotlib: 3.4.2
Pillow: 8.3.1
----------------------------------------
我找到了一个我喜欢的未优化 gif 的解决方案,可能对您有用。
它使用 gifsicle 库,这是一个用于处理 gif 的命令行工具。至关重要的是,gifsicle 可以让你像你一样取消优化 gif(我认为你的 gif 中优化的具体名称是“累积层”)。
使用您选择的包管理器安装它后,您可以通过 Python 的 subprocess 库在您的代码中调用它,或者您自己从命令行使用它。
您特别提到了一种批量取消优化的方法,您可以使用 gifsicle 通过类似的方式非常轻松地做到这一点:
gifsicle -U -b *.gif
这将同时用未优化的版本覆盖工作目录中的每个 gif。如果您想保留优化的副本,请进行备份。有关如何使用 gifsicle 的更多信息,请参阅 manual page。
gif未优化后python应该可以正常打开
所以这个 GIF 在打开之前看起来非常完美:
但是,当使用 Pillow 打开时使用
imageObject = Image.open(path.join(petGifs, f"{pokemonName}.gif"))
它出错了,添加了与源图像颜色相似的各种框。这是一个示例帧,但几乎每一帧都是不同的,并且它在不同的位置取决于 GIF:
唯一解决这个问题的方法是 ezgif 的取消优化选项(在他们的 optimize page 中找到)。但是,我需要在每个 GIF 上都这样做,而且有很多。
我需要一种批量取消优化的方法,或者一种在 Python(目前使用 Pillow)中打开 GIF 的新方法,这将解决这个问题。
您可以尝试使用:
from PIL import Image, ImageSequence
im = Image.open(f"{pokemonName}.gif")
index = 1
for frame in ImageSequence.Iterator(im):
frame.save("frame%d.png" % index)
index += 1
至少对于提取正确的单帧可能有一个解决方案。
所有帧(第一帧除外)的disposal
方法设置为2
,即“恢复为背景颜色”。
深入了解 Pillow 的源代码,您会找到相应的 line where the disposal method 2
is considered,并且在下文中,您会发现:
# by convention, attempt to use transparency first
color = (
frame_transparency
if frame_transparency is not None
else self.info.get("background", 0)
)
self.dispose = Image.core.fill("P", dispose_size, color)
如果您检查错误的框架,您会注意到不需要的框的这种深绿色位于调色板的位置 0
。因此,似乎选择了错误的颜色进行处理,因为 – 我还不知道为什么 – 选择了上面的 else
案例而不是使用透明度信息 – 本来就在那里!
所以,让我们重写可能有问题的东西:
from PIL import Image, ImageSequence
# Open GIF
gif = Image.open('223vK.gif')
# Initialize list of extracted frames
frames = []
for frame in ImageSequence.Iterator(gif):
# If dispose is set, and color is set to 0, use transparency information
if frame.dispose is not None and frame.dispose[0] == 0:
frame.dispose = Image.core.fill('P', frame.dispose.size,
frame.info['transparency'])
# Convert frame to RGBA
frames.append(frame.convert('RGBA'))
# Visualization overhead
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 8))
for i, f in enumerate(frames, start=1):
plt.subplot(8, 8, i), plt.imshow(f), plt.axis('off')
plt.tight_layout(), plt.show()
提取的帧如下所示:
我觉得不错。
如果偶然将透明度信息实际设置为 0
,则此处不应造成任何伤害,因为我们(重新)设置了仍然正确的透明度信息。
我不知道,(重新)保存到 GIF 是否可行,因为帧现在处于 RGBA
模式,从那里保存到 GIF 也很棘手。
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.19041-SP0
Python: 3.9.1
PyCharm: 2021.1.3
Matplotlib: 3.4.2
Pillow: 8.3.1
----------------------------------------
我找到了一个我喜欢的未优化 gif 的解决方案,可能对您有用。
它使用 gifsicle 库,这是一个用于处理 gif 的命令行工具。至关重要的是,gifsicle 可以让你像你一样取消优化 gif(我认为你的 gif 中优化的具体名称是“累积层”)。
使用您选择的包管理器安装它后,您可以通过 Python 的 subprocess 库在您的代码中调用它,或者您自己从命令行使用它。
您特别提到了一种批量取消优化的方法,您可以使用 gifsicle 通过类似的方式非常轻松地做到这一点:
gifsicle -U -b *.gif
这将同时用未优化的版本覆盖工作目录中的每个 gif。如果您想保留优化的副本,请进行备份。有关如何使用 gifsicle 的更多信息,请参阅 manual page。
gif未优化后python应该可以正常打开