PIL - 将 GIF 帧转换为 JPG

新手上路,请多包涵

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

输入 gif 是:

源图片 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

但它会产生奇怪的输出文件:

示例 #1 http://longcat.de/gif_example1.jpg

我的第二次尝试是,首先将 gif 转换为 RGBA,然后使用其透明蒙版,使透明部分变为白色:

 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

与第一次尝试相比的优势在于,第一帧看起来不错但是如您所见,其余部分已损坏

接下来我应该尝试什么?

编辑:

我想我离解决方案更近了

示例 #3 http://longcat.de/gif_example3.png

我必须对其他图像使用第一张图像的调色板,并将其与前一帧合并(对于使用差异图像的 gif 动画)

 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

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

原文由 Schinken 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

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

在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述

 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')

原文由 fraxel 发布,翻译遵循 CC BY-SA 3.0 许可协议

来源在这里

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

原文由 Jamie.C 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题