En Android se suele usar un ImageView para dibujar una imagen. La imagen puede provenir de un recurso interno, de una imagen externa, o de un objeto drawable que se le pase directamente al método .setImageDrawable().
En cualquier caso, en la mayoría de dispositivos no será posible mostrar en este tipo de contenedor un gif animado, ya que según la documentación tan solo se representará el primer frame de la imagen animada.
El modo de representar correctamente una animación en android es usando un recurso creado específicamente para ello. De los dos tipos de animaciones que se pueden crear en Android la que nos interesa en esta ocasión es la que se conoce como Frame Animation. La idea es sencilla y es muy similar a la de los GIF animados: un archivo xml define qué imágenes se muestran y durante cuánto tiempo, las imágenes deben de encontrarse accesibles como recursos internos de la aplicación. Para más información véase la documentación sobre Frame Animation.
La cuestión es que hay un montón de GIFs animados que podemos querer incluir en nuestra aplicación para Android, así que es necesario hacer una conversión de un formato a otro de un modo más o menos automatizado.
El siguiente guión en python extrae los frames completos así como la información temporal y espacial de cada uno de ellos regenerando imágenes en caso de tratarse de un GIF optimizado, para formar un recurso de imagen completo para Android. La animación así creada funcionará correctamente en cualquier dispositivo en cualquier versión de Android. Para más información véase la clase AnimationDrawable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #!/usr/bin/env python # -*- encoding: utf-8 -*- import sys, os import subprocess # When no delay is specified in a gif file, 100ms is default DEFAULT_DELAY_MS = 100 input_file = None output_file = None try: input_file = sys.argv[1] output_file = "%s.xml" % (input_file.split(".")[0],) except: print "Usage: %s <input.gif>" % (sys.argv[0],) sys.exit(1) class Anim(object): def __init__(self): self.content = [] def add_header(self): self.content.append('<?xml version="1.0" encoding="utf-8"?>\n') self.content.append('<animation-list\n') self.content.append(' xmlns:android="http://schemas.android.com/apk/res/android"\n') self.content.append(' android:oneshot="false">\n') def add_item(self, resource, duration): self.content.append( ' <item android:drawable="@drawable/%s" android:duration="%d" />\n' % (resource, duration)) def add_footer(self): self.content.append('</animation-list>\n') def write_file(self): file_descriptor = open(output_file, "w") file_descriptor.writelines(self.content) file_descriptor.close() class Gif(object): def __init__(self, gif): self.input_file = gif gif_info = subprocess.Popen( ["gifsicle", "--info", input_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (gif_info_out, gif_info_error) = gif_info.communicate() self.gif_info_lines = gif_info_out.splitlines() def get_info(self): return self.gif_info_lines def explode(self): return_code = subprocess.call( ["gifsicle", "--explode", "--unoptimize", self.input_file]) return not return_code def to_png(self, gif_frame): return_code = subprocess.call(["gif2png", "-d", "-s", "-O", gif_frame]) return return_code def main(): print "Processing %s..." % (input_file,) anim = Anim() anim.add_header() gif = Gif(input_file) if not gif.explode(): print "Error exploding gif input file %s" % (input_file,) #sys.exit(1) info_lines = gif.get_info() counter = 0 for line in info_lines: line = line.strip() if line.startswith("disposal"): line_items = line.split() if len(line_items) == 4: milliseconds = int(round(float(line_items[3][:-1]) * 1000)) else: milliseconds = DEFAULT_DELAY_MS # Rename and convert gif to optimized png renamed_gif = "%s_%03d.gif" % (input_file.split(".")[0], counter) os.rename("%s.%03d" % (input_file, counter), renamed_gif) result = gif.to_png(renamed_gif) anim.add_item(renamed_gif.split(".")[0], milliseconds) counter = counter + 1 anim.add_footer() anim.write_file() os.unlink(input_file) sys.exit(0) if __name__ == "__main__": main() |
Es necesario tener instalado gifsicle, y para la optimización en tamaño y conversión a png de las imágenes resultantes es necesario tener también instalado, y en el $PATH, gif2png.
Descargar getanim.py.
Etiquetas: android, animación, gif, java, Programación
2 comentarios en “Uso de gif animado en Android”
febrero 8th, 2011 en 20:49
Gracias a ti mis monitos vienen conmigo a todas partes!! :)
mayo 14th, 2011 en 12:17
[…] la entrada anterior vimos cómo convertir un gif animado en una animación para Android. Lo siguiente que queremos […]