2012-04-22 71 views
14

我想一個GIF轉換爲單個圖像使用Python圖像庫, 但它會導致怪異幀PIL - 轉換GIF幀爲JPG

輸入的GIF是:

Source Image 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 

,但它會導致奇怪的輸出文件:

Example #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 

,這導致這樣的輸出:

Example #2 http://longcat.de/gif_example2.jpg

在第一次嘗試的優點是,第一幀看起來很不錯,但 如你所看到的,剩下的就是打破

我應該嘗試下呢?

編輯:

我想我走近解決了很多

Example #3 http://longcat.de/gif_example3.png

我不得不使用第一圖像的調色板,對其他影像, 並與它合併前一幀(對於使用 DIFF-圖像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 

但是I AC tually不知道,爲什麼我的透明度是黑色的,而不是白色 即使我修改調色板(更改透明度通道白色) 或使用透明面罩,背景仍然是黑色

回答

18

首先,JPEG不支持透明度!但這不是唯一的問題..當您移動到GIF的下一幀時,palette信息將丟失(problem witn PIL?) - 因此PIL無法正確轉換爲RGBA框架(因此第一幀是好的,但所有其他幀都是扭曲的)。因此,解決方法是爲每個幀添加palette(這是您在最後一個代碼示例中所做的,但是您的問題是您保存爲RGB而不是RGBA,因此您沒有Alpha /透明度通道。你也在做一些不必要的事情..)。總之,這裏是巴紐的透明度和更正後的代碼,希望一些使用:)

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

非常感謝!我在最後一幀使用粘貼,因爲有些gif使用每幀的差異! – Schinken 2012-04-26 19:41:00

+1

嗯,如果這些框架具有不同的調色板,那麼替換調色板會導致錯誤的結果。這是圖像http://www.imagemagick.org/Usage/anim_opt/bunny_bgnd.gif(我想,不知道我是否複製並粘貼正確的鏈接)。我看到的另一個問題可能與PIL版本之間的差異有關,但我得不到與您的結果相同的結果(我在除第一個之外的所有幀中獲得了灰色區域,它們應該是透明的)。對於像http://www.imagemagick.org/Usage/anim_opt/bunny_bgnd_opttrans.gif這樣的gif也是如此。 – mmgp 2013-01-28 04:31:16

+0

@mmgp - 嗯,是的,我可以看到具有不同調色板的框架可能會造成問題。我同意你得到不同的結果可能是版本問題。不幸的是,我目前沒有時間看這個,如果你有修復,請修改我的答案,或者添加你自己的答案。好一個。 – fraxel 2013-01-28 10:56:09

4

當觀看上的圖像即使透明度設置爲零,圖像查看器也傾向於將圖像顯示爲黑色。確保圖像真正透明的一種方法是將其合併到另一個上。在「表情」應該同時不妨礙其他image.Try可以看出:

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圖像,那麼你肯定會知道,如果它只是圖像查看器和圖像很好...

+0

JPEG格式不支持透明度及其:( – fraxel 2012-04-26 14:45:28