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