espaƱol book python image-processing python-imaging-library gif jpeg

python - book - PIL-Convierte GIF a JPG



django (2)

Intenté convertir un gif a una sola imagen con la Biblioteca de imágenes de Python, pero da como resultado marcos extraños

El gif de entrada es:

Imagen de origen http://longcat.de/gif_example.gif

En mi primer intento, intenté convertir la imagen con Image.new a una imagen RGB, con 255,255,255 como fondo blanco, como en cualquier otro ejemplo que he encontrado en Internet:

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

pero resulta en archivos de salida extraños:

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

Mi segundo intento fue, convertir el gif en un RGBA primero, y luego usar su máscara de transparencia, para hacer que las piezas transparentes se vuelvan blancas:

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

lo que resulta en una salida como esta:

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

La ventaja sobre el primer intento fue que el primer cuadro se ve bastante bien, pero como puede ver, el resto está roto.

¿Qué debo intentar a continuación?

Editar:

Creo que me acerqué mucho más a la solución.

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

Tuve que usar la paleta de la primera imagen para las otras imágenes, y combinarla con el cuadro anterior (para animaciones gif que usan imágenes de diferencias)

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

Pero en realidad no sé por qué mi transparencia es negra, en lugar de blanca. Aunque modifique la paleta (cambie el canal de transparencia a blanco) o use la máscara de transparencia, el fondo sigue siendo negro.


Cuando se ve una imagen en un visor de imágenes, incluso cuando la transparencia se establece en cero, tiende a mostrar la imagen en negro. Una forma de asegurarse de que su imagen sea verdaderamente transparente es fusionarla sobre otra. El ''emoticon'' debe verse sin obstruir la otra imagen. Intente:

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

Teóricamente, si abres ''trial.jpg'' en el visor de imágenes y el contenido de la imagen inicial se conserva y encima de ella se encuentra la imagen de foo, entonces sabrás con seguridad si solo es el visor de imágenes y tus imágenes están bien. ...


En primer lugar, JPEG no es compatible con la transparencia! Pero ese no es el único problema ... Al pasar al siguiente cuadro del GIF la información de la palette se pierde (¿ problema con PIL? ), Por lo que PIL no puede convertirse correctamente al marco RGBA (por lo tanto, el primer cuadro es correcto, pero todos los demás son chiflados). Entonces, la solución es volver a agregar la palette a cada fotograma (lo que estaba haciendo en su último ejemplo de código, pero su problema era que estaba guardando como RGB no RGBA por lo que no tenía un canal alfa / transparencia). También estabas haciendo algunas cosas innecesarias ...). De todos modos, aquí están los .png con transparencia y el código corregido, espero que sea de alguna utilidad :)

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