PIL - 将GIF帧转换为JPG

时间:2012-04-22 15:11:04

标签: python image-processing python-imaging-library gif jpeg

我尝试使用Python Image Library将gif转换为单个图像, 但它导致奇怪的帧

输入gif是:

Source Image http://longcat.de/gif_example.gif

在我的第一次尝试中,我尝试将Image.new转换为图像 RGB图像,255,255,255为白色背景 - 与其他任何图像一样 我在互联网上找到的例子:

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

但它导致奇怪的输出文件:

Example #1 http://longcat.de/gif_example1.jpg

我的第二次尝试是,首先在RGBA中转换gif,然后使用 它的透明度掩模,使透明的部分变白:

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

会产生如下输出:

Example #2 http://longcat.de/gif_example2.jpg

第一次尝试的优势在于,第一帧看起来相当不错 但正如你所看到的,其余部分已被打破

我接下来应该尝试什么?

编辑:

我认为我更接近解决方案

Example #3 http://longcat.de/gif_example3.png

我不得不将第一张图片的调色板用于其他图片, 并将其与前一帧合并(对于使用的gif动画 DIFF-图像)

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

但实际上我不知道,为什么我的透明度是黑色的,而不是白色 即使我修改调色板(将透明度通道更改为白色) 或使用透明蒙版,背景仍为黑色

3 个答案:

答案 0 :(得分:19)

首先,JPEG不支持透明度!但这不是唯一的问题..当您移动到GIF的下一帧时palette信息丢失(problem witn PIL?) - 所以PIL无法正确转换到RGBA框架(因此第一帧是好的,但所有其他框架都很复杂)。因此,解决方法是为每个帧添加palette(这是您在上一个代码示例中所做的,但是您遇到的问题是您保存为RGB而不是{{ 1}}所以你没有alpha /透明度通道。你也做了一些不必要的事情......)。无论如何,这里是带有透明度和更正代码的.png,希望它有一些用处:)

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here {{ 0}}

RGBA

答案 1 :(得分:4)

在图像查看器上查看图像时,即使将透明度设置为零,也会将图像显示为黑色。确保图像真正透明的一种方法是将图像合并到另一个图像上。应该看到'表情符号'而不妨碍另一个图像。试试:

background = Image.open('someimage.jpg') #an existing image
foreground = Image.open('foo.jpg') #one of the above images
background.paste(foreground, (0,0), foreground)
background.save('trial.jpg') #the composite image

理论上,如果您在图像查看器中打开'trial.jpg'并保留初始图像的内容,并且在foo图像的顶部就是foo图像,那么您肯定知道它是否只是图像查看器和您的图像很好......

答案 2 :(得分:0)

source here

Image.open('image.gif').convert('RGB').save('image.jpg')