本文介绍了PIL - 将 GIF 帧转换为 JPG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 04:19