web-dev-qa-db-ja.com

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

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

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

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

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

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

編集:

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

例3 http://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

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

16
Schinken

まず第一に、JPEGは透明性をサポートしていません!しかし、それだけが問題ではありません。GIFの次のフレームに移動すると、palette情報が失われます( PILの問題? )-so PILRGBAフレームワークに正しく変換できません(したがって、最初のフレームは問題ありませんが、他のすべてのフレームは厄介です)。したがって、回避策は、フレームごとにpaletteを追加し直すことです(これは、最後のコード例で行っていたことですが、問題は、RGBとして保存していないことでした。 RGBAなので、アルファ/透明チャンネルがありませんでした。また、いくつかの不要なことをしていました。とにかく、ここに透明性と修正されたコードを備えた.pngがあります、それがいくつかの使用を願っています:)

enter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description hereenter image description here

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

画像ビューアで画像を表示する場合、透明度をゼロに設定しても、画像が黒く表示される傾向があります。画像が本当に透明であることを確認する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画像がある場合、それが画像ビューアだけであり、画像に問題がないかどうかが確実にわかります。 .。。

4
butteredtoast

ソースはこちら

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