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
しかし、実際には、透明度が白ではなく黒である理由がわかりません。パレットを変更したり(透明度チャネルを白に変更したり)、透明度マスクを使用しても、背景は黒のままです。
まず第一に、JPEG
は透明性をサポートしていません!しかし、それだけが問題ではありません。GIF
の次のフレームに移動すると、palette
情報が失われます( PILの問題? )-so 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')
画像ビューアで画像を表示する場合、透明度をゼロに設定しても、画像が黒く表示される傾向があります。画像が本当に透明であることを確認する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画像がある場合、それが画像ビューアだけであり、画像に問題がないかどうかが確実にわかります。 .。。
Image.open('image.gif').convert('RGB').save('image.jpg')