El formato gráfico GIF es de sobra conocido. Puede albergar varias imágenes y soportar pequeñas animaciones. Es un formato comprimido basado en el algoritmo LZW sin pérdida de calidad pero sólo hasta 256 colores.
Gif es un verdadero protocolo de transmisión de gráficos o un formato de archivo orientado a stream soportando entrelazado.
Todo archivo Gif comienza con una cabecera identificadora, con una firma (GIF 87a ó GIF 89a) y los datos del descriptor de pantalla. Seguidamente pero opcional, tendríamos la paleta global y los datos de las imágenes. Los datos se empaquetan en bloques de longitud máxima 255 bytes. Cada bloque tiene una estructura idéntica que comienza con un Byte en el que se guarda el tamaño de los datos que lo siguen. Existen Extensiones adicionales que no son de imagen propiamente dicha como Graphic Control Extension, Comment Extension, Plain Text Extensión y Application Extension.
Cada extensión comienza con un Byte identificador de extensión (carácter '!'), un byte de firma o tipo de extensión, los datos en bloques (con el formato antes descrito) y un bloque terminador nulo (un Byte 0). Más información aquí.
Publico una clase que he escrito para el manejo de los archivos GIF escrita en C++ y en delphi. Dicha clase reúne casi todas las especificaciones GIF 89a y una Extensión de aplicación que permite el Loop de las imágenes (NETSCAPE 2.0). De forma que podremos visualizar o crear pequeñas animaciones GIF.
Las funciones básicas de la clase son:
Constructor por defecto, desde Un archivo o desde un Bitmap
LoadFromFile: Carga un archivo
LoadFromStream: Carga un Gif desde un Stream que porta una imagen de archivo.
SaveToFile: Guarda un archive.
IsOk: True si el gif no causó errores.
GetBitmapCount: Obtiene el número de imágenes de un Gif
IsFormat: Estudia si un archivo tiene cabecera Gif válida
GetBitmap: Devuelve un Bitmap según un índice
GetGraphicBlock: Devuelve un puntero a una estructura Gráfica (TGraphicBlock)
AddGraphicBlock: Añade un TGraphicBlock a la lista del Gif
SetGraphicBlock
InsertGraphicBlock
DeleteGraphicBlock
En la versión Builder C++ tenemos el operador:
operator Graphics::TBitmap*(); Con el que conseguimos el casting a la primera imagen almacenada.
La clase guarda una lista de TGraphicBlock. Cada uno guarda una imagen y datos adicionales de la misma. Esos datos se utilizaran para realizar nuestro visor gif. De ellos Bitmap representa la imagen o fotograma actual y DelayTime el tiempo que se mostrará esa imagen:
TGraphicBlock = record Bitmap: TBitmap; // La Imagen Method: BYTE; // Método de borrado de la Imagen: // 0: Sin acción específica // 1: No se quita la imagen // 2: Se restaura al color de fondo // 3: Se restaura al estado previo el área sobrescrita UserInput: BYTE; // bool DelayTime: WORD; // Tiempo de retardo para cambiar la Imagen Transparency: BYTE; // bool TransparentColorIndex: BYTE; Left: DWORD; // Posición del Bitmap en la Ventana gráfica Top: DWORD; end; PGraphicBlock = ^TGraphicBlock;
struct TGraphicBlock{ Graphics::TBitmap* Bitmap; // La Imagen BYTE Method; // Método de borrado de la Imagen: // 0: Sin acción específica // 1: No se quita la imagen // 2: Se restaura al color de fondo // 3: Se restaura al estado previo el área sobrescrita BYTE UserInput; // bool WORD DelayTime; // Tiempo de retardo para cambiar la Imagen BYTE Transparency; // bool BYTE TransparentColorIndex; DWORD Left; // Posición del Bitmap en la Ventana gráfica DWORD Top; };
Miembros importantes de la clase son:
Interlace: Indica si la imagen es entrelazada
Loop: Indica si las imágenes harán un loop al reproducirlas.
BackgroundColor: El color de fondo
Comments: Un TStringList con una lista de cadenas con los comentarios del GIF (Extensiones de comentario).
Como ejemplo de utilización, publico dos aplicaciones:
1.- Una pequeña aplicación para visualizar y guardar imágenes en formato GIF sin animación.
2.- Otra aplicación que visualiza animaciones GIF. Como ejemplo, esta aplicación guarda un gif en un archivo mediante una lista de fotogramas de un Gif previamente leído. Es un simple ejemplo de como crear un gif animado desde bitmaps.
Los ejemplos son tremendamente sencillos, pero se pueden complicar un poco más para crear una pequeña aplicación que nos permita crear nuestras propias animaciones GIF
Espero que este código sea de utilidad para las aplicaciones tanto delphi como Builder o al menos aclare algo sobre el formato Gif.
¡ATENCIÓN! La clase ha sido revisada y actualizada para las versiones delphi + berlin, Builder + Berlin y Lazarus v1.8.4. Los enlaces de estas versiones los tenéis aquí: TGif V 3.2 y TGif V 3.3
Nueva actualización que añade LoadFromStream aquí: TGIF V 3.5
Saludos.