2012-04-22 10 views
14

ich versucht, ein gif auf einzelne Bilder mit Python Bildbibliothek zu konvertieren, aber es führt zu seltsamen RahmenPIL - Convert GIF Frames zu JPG

Der Input gif ist:

Source Image http://longcat.de/gif_example.gif

In Mein erster Versuch, ich habe versucht, das Bild mit Image.new zu einem RGB-Bild zu konvertieren, mit 255.255.255 als weißen Hintergrund - wie in jedem anderen Beispiel habe ich im Internet gefunden:

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 

aber es führt zu seltsamen Ausgabedateien:

Example #1 http://longcat.de/gif_example1.jpg

Mein zweiter Versuch war, die gif in einem RGBA ersten zu konvertieren und dann seine Transparenzmaske verwenden, um die transparenten Stücke weiß zu machen:

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 

, die in einer Ausgabe wie folgt ergibt:

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

Der Vorteil gegenüber dem ersten Versuch war, dass der erste Rahmen sieht ziemlich gut Aber wie Sie sehen können, ist der Rest gebrochen

Was soll ich als nächstes versuchen?

Edit:

Ich glaube, ich auf die Lösung mit der

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

ich die Palette des ersten Bildes für die anderen Bilder zu verwenden hatte, und verschmelzen sie ein gutes Stück näher gekommen vorheriger Frame (für gIF-Animationen, die diff-Bilder verwenden)

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 

Aber ich ac Dont tually wissen, warum meine Transparenz ist schwarz, statt weiß Auch wenn ich die Palette ändern (ändern Sie den Transparenzkanal weiß) oder die Transparenzmaske verwenden, ist der Hintergrund immer noch schwarz

Antwort

18

Zunächst einmal JPEG unterstützt keine Transparenz! Aber das ist nicht das einzige Problem ..Wenn Sie zum nächsten Frame der GIF gehen, gehen die palette Informationen verloren (problem witn PIL?) - so kann PIL nicht korrekt in das RGBA Framework konvertiert werden (Daher ist das erste Frame okish, aber alle anderen sind verrückt). Das Problem besteht also darin, die palette für jeden Frame wieder hinzuzufügen (was Sie in Ihrem letzten Codebeispiel getan haben, aber Ihr Problem war, dass Sie als RGB nicht RGBA gespart haben, also hatten Sie keinen Alpha/Transparenz-Kanal. Außerdem hast du ein paar unnötige Dinge getan ..). Wie auch immer, hier sind die .png die mit Transparenz und dem korrigierten Code, hoffen seine von Nutzen :)

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

Vielen Dank! Ich benutze Einfügen mit dem letzten Rahmen, weil einige Gifs Diffs für jeden Rahmen verwendet! – Schinken

+1

Uhm, ersetzt die Palette wie das wird falsche Ergebnisse geben, wenn die Rahmen verschiedene Paletten haben. Ein Beispiel für das ist das Bild http://www.imagemagick.org/Usage/anim_opt/bunny_bgnd.gif (Ich denke, ich bin mir nicht sicher, ob ich die richtigen Links kopiere und einfüge). Das andere Problem, das ich sehe, könnte mit den Unterschieden zwischen PIL-Versionen zusammenhängen, aber ich bekomme nicht das gleiche Ergebnis wie Ihres (ich bekomme graue Bereiche in allen Frames außer dem ersten, wo es hätte transparent sein sollen). Das gleiche passiert für ein gif wie http://www.imagemagick.org/Usage/anim_opt/bunny_bgnd_opttrans.gif. – mmgp

+0

@mmgp - hmm, yep Ich kann sehen, dass Frames mit verschiedenen Paletten ein Problem darstellen könnten. Ich stimme zu, dass das Abrufen anderer Ergebnisse ein Versionsfehler sein könnte. Leider habe ich im Moment keine Zeit, das zu betrachten, wenn Sie eine Lösung haben, bearbeiten Sie bitte meine Antwort oder fügen Sie Ihre eigene hinzu. Schön. – fraxel

4

Wenn auf eine Anzeige eines Bildes Bildbetrachter, auch wenn Transparenz auf Null gesetzt ist, neigt es dazu, das Bild als schwarz anzuzeigen. Eine Möglichkeit, um sicherzustellen, dass Ihr Bild wirklich transparent ist, besteht darin, es über ein anderes zu verschmelzen.

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 

Theoretisch, wenn Sie ‚trial.jpg‘ im Bildbetrachter und der Inhalt des Ausgangsbildes geöffnet bleibt erhalten und obendrein: Die ‚Emoticon‘ sollte zwar nicht zu behindern den anderen image.Try zu sehen es liegt das foo Bild, dann wissen Sie sicher, ob es nur der Bildbetrachter und Ihre Bilder sind in Ordnung ...

+0

Jpeg unterstützt keine Transparenz :( – fraxel

Verwandte Themen