2012-04-22 4 views
14

Я пытался конвертировать GIF в отдельных изображений с Python Image Library, , но это приводит к странным кадровPIL - Преобразование Frames 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

Преимущества по сравнению с первой попыткой был, что первый кадр выглядит довольно хорошо Но как вы можете видеть, остальное сломан

Что я должен попробовать следующее?

Edit:

Я думаю, что я пришел гораздо ближе к решению

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

мне пришлось использовать палитру первого изображения для других изображений, и объединить его с предыдущий кадр (для GIF анимации, которые используют Diff-изображения)

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 

Но я ас tually не знаю, почему моя прозрачность черный, а не белый Даже если я изменить палитру (изменить канал прозрачности на белый) или использовать маску прозрачности, фон по-прежнему черный

ответ

18

Прежде всего, JPEG не поддерживает прозрачность! Но это не единственная проблема.Когда вы переходите к следующему кадру GIF, информация palette теряется (problem witn PIL?) - так PIL не в состоянии правильно преобразовать в каркас RGBA (Следовательно, первый кадр окуривает, но все остальные винтовые). Таким образом, работа заключается в том, чтобы добавить 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') 
+0

Большое спасибо! Я использую вставку с последним фреймом, потому что некоторые gifs используют diff для каждого кадра! – Schinken

+1

Uhm, заменив подобную палитру, даст неправильные результаты, когда кадры имеют разные палитры. то есть изображение http://www.imagemagick.org/Usage/anim_opt/bunny_bgnd.gif (я думаю, не уверен, что я копирую и вставляю правильные ссылки). Другая проблема, которую я вижу, может быть связана с различиями между версиями PIL, но я не получаю такой же результат, как ваш (я получаю серые области во всех кадрах, кроме первого, где он должен быть прозрачным). То же самое происходит для gif, например http://www.imagemagick.org/Usage/anim_opt/bunny_bgnd_opttrans.gif. – mmgp

+0

@mmgp - хм, да, я вижу, что кадры с разными палитрами могут создать проблему. Я согласен, что вы получаете разные результаты, может быть, проблема с версией. К сожалению, у меня нет времени, чтобы посмотреть на это в данный момент, если у вас есть исправление, отредактируйте мой ответ или добавьте свое. хороший. – fraxel

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

Смежные вопросы