动画GIF仅在其第一帧(Python PIL)上是透明的

2024-04-29 18:31:01 发布

您现在位置:Python中文网/ 问答频道 /正文

以下代码从两个图像创建GIF:

# GIFs are always palette images so they would be converted later anyway
im1 = PIL.Image.open('grin-emoji-by-twitter-rgba.png').convert('P')
im2 = PIL.Image.open('grin-emoji-by-twitter-rgba-2.png').convert('P')

im1.save('output.gif', save_all=True, append_images=[im2, im1, im2], loop=0, duration=200, transparency=255)

然而,结果却出人意料地错了。第一帧很好,但后续帧包含更新区域周围的黑色矩形,而不是透明度:

enter image description here

在我看来,错误如下:在第一幅图像上,我们指定索引255作为完全透明颜色的索引。但是save函数似乎只在第一帧上将索引255转换为透明度,但在所有其他帧上跳过此步骤

有什么办法可以避免这种情况吗


Tags: 图像imageconvertbypilpngsavetwitter
2条回答

作为我另一个答案的替代方案,您也可以只set the ^{} value to 2

im1.save('output.gif', save_all=True, append_images=[im2, im1, im2], 
         loop=0, duration=200, transparency=255, disposal=2)

请注意,与我的其他答案不同,这并不是100%都有效,因为透明度通道可以跳转到其他索引。:/然而,这似乎只发生在有许多颜色的较长GIF中

左:此答案,右:手动对齐的其他答案

example of bug persistingexample of bug fixed

编辑:Here据称这在新版枕头中得到了修复!(我认为是8.1.2+)

是的,有办法我们可以手动编辑调色板以将透明度从索引255移动到0。save如果透明度位于索引0而不是255,则不会出现错误

我通过将整个调色板右移一个索引来实现这一点,因此索引5变为索引6,索引255变为索引0,依此类推

在最坏的情况下(例如长彩色GIF),透明度并不总是在索引255处,我们必须手动将其与索引0对齐(请参见shiftme行)

im1 = PIL.Image.open('grin-emoji-by-twitter-rgba.png').convert('P')
im2 = PIL.Image.open('grin-emoji-by-twitter-rgba-2.png').convert('P')

p1 = im1.getpalette()
p2 = im2.getpalette()

# if you know a data point in the resulting image that will be
# transparent you can also set it directly e.g. 'shiftme = -frame[0][0]'
shiftme = 1       
im1 = (numpy.array(im1) + shiftme) % 256  # shift data pointing into palette
im2 = (numpy.array(im2) + shiftme) % 256

im1 = PIL.Image.fromarray( im1 ).convert('P')
im2 = PIL.Image.fromarray( im2 ).convert('P')

im1.putpalette( p1[-3*shiftme:] + p1[:-3*shiftme] )  # shift palette
im2.putpalette( p2[-3*shiftme:] + p2[:-3*shiftme] )  # NB this is NOT '-4' as it is RGB not RGBA

print(numpy.array(im1))
print(numpy.array(im2))

im1.save('output.gif', save_all=True, append_images=[im2, im1, im2], loop=0, duration=200, transparency=0)

结果😁

enter image description here

相关问题 更多 >