问题描述
我尝试使用 Python 图像库将 gif 转换为单个图像,但它会导致奇怪的帧
I tried to convert an gif to single images with Python Image Library,but it results in weird frames
输入 gif 是:
源图片 http://longcat.de/gif_example.gif
在我的第一次尝试中,我尝试将 Image.new 的图像转换为RGB 图像,以 255,255,255 作为白色背景 - 就像任何其他图像一样我在网上找到的例子:
In my first try, i tried to convert the image with Image.new to anRGB image, with 255,255,255 as white background - like in any otherexample i've found on the internet:
def processImage( infile ):
try:
im = Image.open( infile )
except IOError:
print "Cant load", infile
sys.exit(1)
i = 0
try:
while 1:
background = Image.new("RGB", im.size, (255, 255, 255))
background.paste(im)
background.save('foo'+str(i)+'.jpg', 'JPEG', quality=80)
i += 1
im.seek( im.tell() + 1 )
except EOFError:
pass # end of sequence
但它会导致奇怪的输出文件:
but it results in weird output files:
示例 #1 http://longcat.de/gif_example1.jpg
我的第二次尝试是,首先将 gif 转换为 RGBA,然后使用它的透明蒙版,使透明块变白:
My second try was, to convert the gif in an RGBA first, and then useits transparency mask, to make the transparent pieces white:
def processImage( infile ):
try:
im = Image.open( infile )
except IOError:
print "Cant load", infile
sys.exit(1)
i = 0
try:
while 1:
im2 = im.convert('RGBA')
im2.load()
background = Image.new("RGB", im2.size, (255, 255, 255))
background.paste(im2, mask = im2.split()[3] )
background.save('foo'+str(i)+'.jpg', 'JPEG', quality=80)
i += 1
im.seek( im.tell() + 1 )
except EOFError:
pass # end of sequence
结果如下:
示例#2 http://longcat.de/gif_example2.jpg
比第一次尝试的优势在于,第一帧看起来很不错但正如你所看到的,其余的都坏了
The advantage over the first try was, that the first frame looks pretty goodBut as you can see, the rest is broken
接下来我应该尝试什么?
What should i try next?
我想我离解决方案更近了
I think i came a lot closer to the solution
示例 #3 http://longcat.de/gif_example3.png
对于其他图像,我不得不使用第一张图像的调色板,并将其与前一帧合并(对于使用差异图像)
I had to use the palette of the first image for the other images,and merge it with the previous frame (for gif animations which usediff-images)
def processImage( infile ):
try:
im = Image.open( infile )
except IOError:
print "Cant load", infile
sys.exit(1)
i = 0
size = im.size
lastframe = im.convert('RGBA')
mypalette = im.getpalette()
try:
while 1:
im2 = im.copy()
im2.putpalette( mypalette )
background = Image.new("RGB", size, (255,255,255))
background.paste( lastframe )
background.paste( im2 )
background.save('foo'+str(i)+'.png', 'PNG', quality=80)
lastframe = background
i += 1
im.seek( im.tell() + 1 )
except EOFError:
pass # end of sequence
但我实际上不知道,为什么我的透明度是黑色的,而不是白色的即使我修改调色板(将透明通道更改为白色)或者使用透明蒙版,背景还是黑色
But i actually dont know, why my transparency is black, instead of whiteEven if i modify the palette (change the transparency channel to white)or use the transparency mask, the background is still black
推荐答案
首先,JPEG
不支持透明!但这并不是唯一的问题.当您移动到 GIF
的下一帧时,palette
信息丢失了(PIL 有问题?) - 所以 PIL
无法正确转换为 RGBA
框架(因此第一帧很不错,但其他所有帧都很糟糕).因此,解决方法是为每一帧重新添加 palette
(这是您在上一个代码示例中所做的,但您的麻烦在于您将其另存为 RGB
不是 RGBA
所以你没有 alpha/透明通道.而且你做了一些不必要的事情......).无论如何,这里是具有透明度的 .png 和更正后的代码,希望它有一些用处:)
First of all, JPEG
doesn't support transparency! But that's not the only problem.. As you move to the next frame of the GIF
the palette
information is lost (problem witn PIL?) - so PIL
is unable to correctly convert to the RGBA
framework (Hence the first frame is okish, but all the others are screwy). So the work-around is to add the palette
back in for every frame, (which is what you were doing in your last code example, but your trouble was that you were saving as RGB
not RGBA
so you had no alpha/ transparency channel. Also you were doing a few unnecessary things..). Anyhow, here are the .png's with transparency and the corrected code, hope its of some use :)
import Image
import sys
def processImage(infile):
try:
im = Image.open(infile)
except IOError:
print "Cant load", infile
sys.exit(1)
i = 0
mypalette = im.getpalette()
try:
while 1:
im.putpalette(mypalette)
new_im = Image.new("RGBA", im.size)
new_im.paste(im)
new_im.save('foo'+str(i)+'.png')
i += 1
im.seek(im.tell() + 1)
except EOFError:
pass # end of sequence
processImage('gif_example.gif')
这篇关于PIL - 将 GIF 帧转换为 JPG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!