16

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

しかし、それは奇妙な出力ファイルになります:

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

2番目の試みは、最初に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

これにより、次のような出力が得られます。

例2http://longcat.de/gif_example2.jpg

最初の試行に対する利点は、最初のフレームがかなり見栄えがすることでしたが、ご覧のとおり、残りは壊れています

次に何を試すべきですか?

編集:

私は解決策にかなり近づいたと思います

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

他の画像には最初の画像のパレットを使用し、それを前のフレームとマージする必要がありました(diff-imagesを使用する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

しかし、実際には、透明度が白ではなく黒である理由がわかりません。パレットを変更したり(透明度チャネルを白に変更したり)、透明度マスクを使用しても、背景は黒のままです。

4

4 に答える 4

22

まず第一に、JPEG透明性をサポートしていません!しかし、それだけが問題ではありません。次のフレームに移動するとGIFpalette情報が失われます(PILで問題が発生しますか?) 。そのため、フレームワークPILに正しく変換できませんRGBA(したがって、最初のフレームは問題ありませんが、他のすべてのフレームは問題ありません。ねじれ)。したがって、回避策はpalette、すべてのフレームにバックインを追加することです(これは、最後のコード例で行っていたものですが、問題は、アルファ/透明チャネルがRGBないため、保存していないことでした。また、RGBAいくつかの不必要なことをする..)。とにかく、ここに透明性と修正されたコードを備えた.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')
于 2012-04-26T14:44:38.603 に答える
4

画像ビューアで画像を表示する場合、透明度をゼロに設定しても、画像が黒く表示される傾向があります。画像が本当に透明であることを確認する1つの方法は、画像を別の画像にマージすることです。「絵文字」は、他の画像を遮らないように表示する必要があります。試してみてください。

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画像がある場合、それが画像ビューアだけであり、画像が正常であるかどうかが確実にわかります。 ..。。

于 2012-04-22T19:44:25.030 に答える
3

ソースはこちら

Image.open('image.gif').convert('RGB').save('image.jpg')
于 2019-08-02T11:34:54.540 に答える
0

ここに画像の説明を入力してください

これは私のために働きます。次の例は、image.gifを背景が白の8つのjpg形式の画像に変換する方法を示しています。

from PIL import Image
from PIL import GifImagePlugin


def gif2jpg(file_name: str, num_key_frames: int, trans_color: tuple):
    """
    convert gif to `num_key_frames` images with jpg format
    :param file_name: gif file name
    :param num_key_frames: result images number
    :param trans_color: set converted transparent color in jpg image
    :return:
    """
    with Image.open(file_name) as im:
        for i in range(num_key_frames):
            im.seek(im.n_frames // num_key_frames * i)
            image = im.convert("RGBA")
            datas = image.getdata()
            newData = []
            for item in datas:
                if item[3] == 0:  # if transparent
                    newData.append(trans_color)  # set transparent color in jpg
                else:
                    newData.append(tuple(item[:3]))
            image = Image.new("RGB", im.size)
            image.getdata()
            image.putdata(newData)
            image.save('{}.jpg'.format(i))


gif2jpg("image.gif", 8, (255, 255, 255))  # convert image.gif to 8 jpg images with white background

于 2022-02-17T16:23:00.800 に答える