⚠️ Este es un sitio de traducción no oficial, sin relación con ImageMagick Studio LLC. Para información autorizada, consulte la página original (https://usage.imagemagick.org/anim_opt/index.html).

Ejemplos de ImageMagick -- Optimización de animaciones

Prólogo e índice de los ejemplos de ImageMagick
Introducción a la optimización
El optimizador de GIF de uso general de ImageMagick
Optimización de fotogramas

Introducción a la optimización de animaciones

Optimizar una animación no es fácil, sobre todo una animación GIF, que tiene restricciones de color, además de la posibilidad de elegir entre distintas técnicas de descarte de fotogramas y de usar superposiciones de «subfotogramas» más pequeñas de un fotograma al siguiente. Al optimizar una animación conviene intentar hacerlo en el orden siguiente.

Sin embargo, ese no es el orden en que veremos estas técnicas de optimización. En las animaciones GIF, la optimización de fotogramas es la técnica de optimización más básica y donde se puede ganar más. Por eso la veremos primero. Probablemente el aspecto de la optimización con el que más problemas tienen los usuarios sea la optimización del color, causada por las limitaciones de color de las animaciones GIF. Uno de sus aspectos, la tabla de colores global única, debe hacerse como último paso antes de guardar el GIF, o podría perderse el efecto de los operadores sobre el archivo GIF final guardado.


El optimizador de GIF de uso general de ImageMagick

El método «**Optimize**» de «[-layers](https://imagemagick.org/command-line-options/#layers)» usará varias de las técnicas que veremos en detalle más abajo para intentar optimizar una animación GIF en un único paso razonable. Actualmente esta opción equivale a (en orden)…

En ese punto se puede guardar la animación GIF de inmediato. Estos son pasos de optimización razonablemente seguros que se pueden aplicar a la mayoría de las secuencias de animación, aunque no hay garantía de que el resultado sea una animación GIF más pequeña. Esto es especialmente cierto en una secuencia de vídeo en bruto, donde una optimización de la transparencia suele empeorar la relación de compresión LZW. No obstante, para la mayoría de las animaciones GIF, que contienen imágenes de tipo dibujo animado, el operador «Optimize» debería producir una animación bien optimizada. Aun así, el operador sigue en desarrollo y en el futuro es probable que incluya también pasos de optimización estándar adicionales, como…

  • Un umbral del 50 % del canal alfa, tal como hace IM normalmente al guardar en formato GIF, para eliminar los píxeles semitransparentes. Si lo prefieres, puedes hacer tú mismo el tratamiento de la semitransparencia de antemano para anular esto. Consulta Transparencia booleana de GIF para más detalle.
  • Algún tipo de técnica de optimización del color. Qué tipo exactamente está aún por decidir y podría seleccionarse según la animación y el número de colores implicados. Se agradecen sugerencias.
  • Una tabla de colores global única, es decir, una operación «[+map](https://imagemagick.org/command-line-options/#map)».

Dicho de otro modo, se espera que «Optimize» acabe convirtiéndose en el optimizador genérico de animaciones GIF de IM, para un uso rápido y sencillo por parte de los usuarios de IM. Hasta entonces, ten cuidado con su uso, especialmente en scripts, ya que cambiará. Por supuesto, para una animación concreta muchos de los pasos de optimización pueden no merecer el esfuerzo. Esta opción además probablemente se vuelva bastante lenta. Ese es el plan y el objetivo al que apuntaba esta sección de los ejemplos de IM.


Optimizaciones de fotogramas

La optimización de fotogramas se basa en superponer una subimagen más pequeña en lugar de una superposición completa de toda la imagen. Esto, obviamente, produce un menor número de píxeles y, por tanto, un archivo más pequeño en disco o para enviarlo por la red. Además, superponer un fotograma más pequeño significa que el ordenador cliente no tiene que trabajar tanto para cambiar los píxeles en pantalla. Sin embargo, el formato GIF dispone de distintos métodos de descarte para tratar el último fotograma mostrado, y eso puede dar lugar a superposiciones de distinto tamaño. No solo eso, sino que es posible dividir las superposiciones en varias partes, o acciones de actualización, para conseguir una animación más compleja pero más optimizada. Como la optimización de fotogramas es compleja, lo habitual es eliminar primero cualquier optimización de fotogramas existente mediante la operación «[-coalesce](https://imagemagick.org/command-line-options/#coalesce)». Consulta los ejemplos de Coalesce. Naturalmente, eso significa que también se eliminan las optimizaciones manuales que pudieran existir, así que se aconseja cierta precaución.

Optimización básica de fotogramas

El método «[-deconstruct](https://imagemagick.org/command-line-options/#deconstruct)» produce una optimización de fotogramas básica para una animación GIF. Sin embargo, como se mostró en los ejemplos de Deconstruct de la sección anterior, este operador no funciona con todas las animaciones GIF cuando hay píxeles transparentes de por medio. En concreto, cuando una animación borra a transparente algún píxel coloreado. Es decir, solo funciona con las animaciones de superposición. El método «**OptimizeFrame**» de «[-layers](https://imagemagick.org/command-line-options/#layers)» está diseñado como un optimizador de fotogramas GIF, que intentará encontrar las imágenes de superposición de subfotogramas más pequeñas usando cualquier método de descarte de GIF. El resultado suele ser una animación de descarte mixto, aunque a menudo también generará animaciones de fotograma borrado o animaciones de superposición pura si se determina que esa es la mejor solución para la animación concreta. Recuerda que la animación de entrada debe ser una «animación fusionada», de modo que conste de una secuencia de fotogramas de imagen completos, todos del mismo tamaño y sin desplazamientos de lienzo. Por supuesto, cualquier método de descarte existente en una animación fusionada es del todo irrelevante y el método «OptimizeFrame» lo ignorará. Por ejemplo, probémoslo con una animación de descarte anterior, creada en la sección anterior. | |

  magick canvas_prev.gif -coalesce  -layers OptimizeFrame  optframe.gif
  gif_anim_montage optframe.gif optframe_frames.gif

[IM Output]
[IM Output]
[IM Output]
Como puedes ver, «[-layers](https://imagemagick.org/command-line-options/#layers) OptimizeFrame» devolvió correctamente nuestra animación a su forma original optimizada por fotogramas, usando el descarte anterior. Esta optimización funciona también correctamente para las animaciones de descarte de fondo, más difíciles de tratar… | |

  magick canvas_bgnd.gif -coalesce  -layers OptimizeFrame  optframe_bgnd.gif
  gif_anim_montage optframe_bgnd.gif optframe_bgnd_frames.gif

[IM Output]
[IM Output]
La animación queda perfectamente optimizada por fotogramas usando el descarte de fondo. Este operador funcionará correctamente para todas las animaciones GIF y, por lo general, devolverá la mejor «optimización simple de descarte y fotogramas» posible.
Ahora, malas noticias sobre cualquier tipo de optimización simple de fotogramas, como la que ofrece IM… Aunque «[OptimizeFrame](#optframe)» devuelve la mejor optimización de fotogramas que IM es capaz de averiguar para una animación dada, hay una serie de casos especiales en los que no funciona bien. Estos incluyen…

  • Animaciones donde se necesita borrar píxeles (devolverlos a transparente), pero las superposiciones de fotograma son demasiado grandes para borrar eficientemente las pequeñas zonas de píxeles que hay que borrar (consulta la animación del agujero móvil más abajo).
  • Animaciones con dos o más zonas pequeñas de cambio muy alejadas entre sí. En realidad son bastante comunes y horribles de optimizar por fotogramas. (Consulta División de las actualizaciones de fotograma más abajo)
  • Animaciones con fondos muy complejos que permanecen estáticos durante periodos largos (más de 3 fotogramas), pero que luego cambian ligeramente antes de permanecer estáticos otro periodo largo, etcétera, etcétera, etcétera… O un fondo estático que queda muy oculto durante un periodo muy breve. En esta situación compleja puede ser casi imposible que cualquier algoritmo informático averigüe la «mejor» optimización de fotogramas (es decir, ¿qué debe considerarse fondo estático?). Solo los humanos, con su comprensión intuitiva de lo que ven, pueden generar una buena secuencia de superposición de fotogramas óptima en estos casos.

Se buscan ejemplos de animaciones difíciles de optimizar, por favor contribuye. Si encuentras un ejemplo de animación que IM no logra optimizar bien, mándamelo por correo para estudiarlo más a fondo. Así es como se pueden desarrollar nuevas técnicas y posibles soluciones automáticas. Naturalmente, publicaré tu nombre como contribuyente.

Sin superposición de píxeles - imagen repetida cada dos fotogramas

[animation] ¡A veces la mejor optimización para una imagen consiste en no superponer ningún píxel en absoluto! Por ejemplo, a la derecha hay una animación sencilla, aportada por nixscripter. Si observamos sus fotogramas, verás que no está muy optimizada. Pero fíjate en que cada dos fotogramas de la animación simplemente se repiten.

  gif_anim_montage paddleball.gif paddleball_frames.gif

[IM Output]

Tras optimizarla por fotogramas obtenemos una secuencia de descarte de GIF muy especial. | |

  magick paddleball.gif -coalesce -layers OptimizeFrame  paddleball_opt.gif
  gif_anim_montage paddleball_opt.gif paddleball_opt_frames.gif

[IM Output]
[IM Output]
Lo que ocurre es que, en lugar de superponer el fotograma original, IM eligió recuperar la primera imagen usando un descarte GIF «anterior». Como ese fotograma recuperado se deja tal cual, no hay píxeles que cambien. Así que la superposición de subfotograma se reduce a nada. Por desgracia, ni IM ni el formato GIF permiten tener una imagen de tamaño cero, por lo que en su lugar se usa una imagen mínima especial de un solo píxel transparente. Esta imagen se conoce como imagen omitida, ya que también se usa ampliamente cuando «[-crop](https://imagemagick.org/command-line-options/#crop)» «falla» los datos reales de la imagen, produciendo el mismo resultado. Esta imagen, en efecto, solo conserva los metadatos del fotograma, como el método de descarte, el retardo de tiempo y el número de repeticiones del bucle. Por eso es una parte esencial de la animación, aunque esté «vacía». Así, al superponer un mínimo de un solo píxel transparente, IM ahorró una cantidad enorme de espacio (y tiempo) en esta animación.

Animación del agujero móvil - difícil de optimizar por fotogramas

Aquí tienes un caso extremo de animación GIF que no se optimiza muy bien por fotogramas con ningún método de optimización normal. Esta animación consta básicamente de una imagen de fondo sencilla que no cambia, pero con un «agujero» transparente a través de ese fondo que cambia de posición de un fotograma al siguiente. Para crearla necesito hacer una secuencia de imágenes fusionada, donde recorto un agujero en una imagen de fondo fija usando la composición alfa de capas. También usé el modificador «[+antialias](https://imagemagick.org/command-line-options/#antialias)» para asegurarme de que solo se usen cuatro colores: tres azules y la transparencia. Así no tenemos que lidiar con los problemas de optimización del color. | |

  magick +antialias -size 100x100 -delay 100 xc:SkyBlue -loop 0 \
          -fill DodgerBlue -draw 'circle 50,50 15,25' \
          -fill RoyalBlue  -draw 'circle 50,50 30,25' \
          null: \( -size 100x100 xc:none -draw 'circle 40,25 27,22' \) \
                \( +clone -rotate 90 \) \( +clone -rotate 90 \) \
                \( +clone -rotate 90 \) -compose DstOut -layers Composite \
          -set dispose background  moving_hole.gif
  gif_anim_montage moving_hole.gif moving_hole_frames.gif

[IM Output]
[IM Output]
Como puedes ver, la animación funciona: un «agujero» redondo muestra el color de fondo de esta página, produciendo un archivo de animación de [IM Text] bytes de tamaño. Así que probemos una optimización de fotogramas directa para esta animación. | |

  magick moving_hole.gif  -layers OptimizeFrame  moving_hole_opt.gif
  gif_anim_montage moving_hole_opt.gif moving_hole_opt_frames.gif

[IM Output]
[IM Output]
¡Un momento, no pasó nada! ¡La mejor optimización que IM pudo lograr fue ningún cambio en absoluto! ¿Es la versión fusionada anterior de esta animación la más óptima? Pues para la animación tal como está… sí, ¡esta es realmente la mejor optimización simple que se puede lograr mediante pura optimización de descarte de fotogramas! Nada bueno. El problema es que, para que una animación GIF «borre» o «elimine» los píxeles dibujados por fotogramas anteriores, necesita usar un método de descarte «de fondo». Aunque en algunas situaciones especiales también puede usarse un método de descarte «anterior». Sin embargo, el descarte «de fondo» solo puede borrar zonas que se acaban de superponer. Como el primer fotograma fue una superposición completa de toda la imagen, se borrará toda la imagen. Aunque solo haya que borrar los píxeles de una pequeña sección de la animación. En consecuencia, hay que superponer todo el segundo fotograma, ¡aunque la mayor parte de ese fotograma se acababa de mostrar! Este horrible callejón sin salida continúa a lo largo del resto de la animación, sin producir ninguna optimización de fotogramas básica. Ya dije que esta animación sería difícil de optimizar por fotogramas.

Duplicación de fotogramas - un método para optimizar «agujeros» por fotogramas

Sin embargo, no todo está perdido. Añadiendo algunos fotogramas extra a la animación, puedes darle al método «[OptimizeFrame](#optframe)» cierto margen para aprovechar mejor los métodos de descarte de GIF disponibles. Aquí, por ejemplo, añadimos un fotograma extra duplicando la primera imagen, pero dándole un retardo de tiempo cero para no alterar la temporización general de la animación. | |

  magick moving_hole.gif[0] -set delay 0   moving_hole.gif \
          -layers OptimizeFrame    moving_hole_dup.gif
  gif_anim_montage moving_hole_dup.gif moving_hole_dup_frames.gif

[IM Output]
[IM Output]
Al duplicar el primer fotograma, la animación se redujo de [IM Text] bytes a [IM Text] bytes de tamaño. Así, aunque la animación tiene ahora cinco fotogramas, su tamaño total es mucho menor, gracias a la enorme reducción del tamaño de las superposiciones de imagen de subfotograma. La duplicación separa, en esencia, la función de borrado de píxeles del método de descarte de la función de superposición de píxeles que realiza el fotograma siguiente. Tanto el descarte como la superposición se realizan como parte de la misma actualización de fotograma en los programas de animación GIF, por lo que no debería notarse ninguna pérdida de velocidad o calidad. Esta es una técnica compleja y delicada, que rara vez ven o comprenden los diseñadores de animaciones GIF ni los programas de optimización de GIF, pero sus beneficios bien valen la pena cuando se necesita. No obstante, la reducción del tamaño de las imágenes de subfotograma solo dura poco tiempo, ya que los fotogramas posteriores también tienen que borrar píxeles para el fotograma siguiente, de modo que los fotogramas vuelven a hacerse grandes para seguir borrando píxeles posteriores. Es decir, porque el borrado de píxeles siempre da lugar a fotogramas más grandes, nunca más pequeños. Así que probemos a duplicar todos los fotogramas (excepto el último, que nunca necesita duplicarse) para ver cómo afecta a la imagen final… | |

  magick moving_hole.gif  \( -clone 0--1 -set delay 0 \) \
          +delete -insert 2 -insert 1 -insert 0 \
          -layers OptimizeFrame  moving_hole_double.gif
  gif_anim_montage x2 moving_hole_double.gif moving_hole_double_frames.gif

[IM Output]
[IM Output]
Como puedes ver, aunque tenemos casi el doble de fotogramas, todos los tamaños de imagen son mucho más pequeños, produciendo una animación de [IM Text] bytes, un resultado más pequeño, aunque no un ahorro tan grande como la primera duplicación de un solo fotograma que hicimos. Para que puedas seguir lo que ocurre, el fotograma «[Background](anim_basics.html#background)» es un duplicado exacto del fotograma anterior, sin cambiar nada de lo que se muestra. Sin embargo, define la zona de la animación que hay que borrar antes de superponer la imagen del fotograma siguiente. El fotograma «[None](anim_basics.html#none)» que sigue rellena entonces los píxeles que hay que cambiar, así como los píxeles que el descarte del fotograma anterior borró. En la animación anterior eso significa los píxeles necesarios para dar forma al nuevo agujero, así como los píxeles que se usaron para rellenar el «agujero» anterior. El resultado es más pequeño, pero no tanto, ya que añadir fotogramas extra tiene su propio coste. Al menos, cada uno de los fotogramas añadidos tampoco tiene su propia tabla de colores; de lo contrario, ¡esta animación se habría hecho de hecho más grande, debido al tamaño de las tablas de colores extra!

Layer Optimize Plus - optimización automática por duplicación de fotogramas

Me complace decir que, a partir de la versión 6.2.7, IM puede ahora hacer la optimización por duplicación de fotogramas automáticamente, como parte de su tratamiento normal de optimización de fotogramas. Sin embargo, como añadir fotogramas para hacer una animación más pequeña es una medida tan radical, se le dio su propio método «**OptimizePlus**» de «[-layers](https://imagemagick.org/command-line-options/#layers)». Por ejemplo, hagamos que IM realice la optimización por duplicación de fotogramas… | |

  magick moving_hole.gif  -layers OptimizePlus   moving_hole_oplus.gif
  gif_anim_montage x2 moving_hole_oplus.gif moving_hole_oplus_frames.gif

[IM Output]
[IM Output]
Es decir, IM te dio el mismo resultado que nuestro ejemplo anterior de duplicación de fotogramas. Así, el archivo GIF sigue siendo de [IM Text] bytes. No obstante, «OptimizePlus» solo duplicará fotogramas si se reduce el número de píxeles del fotograma actual y del siguiente de la animación resultante (3 fotogramas), de modo que podemos dejar que IM decida si duplicar o no. Como el método «[OptimizePlus](#optimizeplus)» de «[-layers](https://imagemagick.org/command-line-options/#layers)» añade fotogramas extra al crear una animación GIF optimizada por fotogramas, también eliminará cualquier fotograma innecesario o sobrante que no cambie la animación final (fusionando los tiempos de retardo según convenga). Es decir, también hará un «[RemoveDups](#removedups)» automático (véase a continuación). El método «[OptimizeFrame](#optframe)» no hace esto.

Eliminar fotogramas duplicados - fusionar imágenes duplicadas consecutivas

Por desgracia, si fusionas (coalesce) esta animación, también obtendrás todos los fotogramas extra que se añadieron arriba.

  magick moving_hole_oplus.gif -coalesce gif:- |\
     gif_anim_montage x2 - moving_hole_oplus_cframes.gif

[IM Output]

Para permitirte eliminar esos fotogramas duplicados inútiles de una animación fusionada, se ha proporcionado un método «**RemoveDups**». Este compara cada fotograma con el siguiente de la animación y elimina el primer fotograma si son idénticos (con la similitud de color fijada por el factor de tolerancia (fuzz) actual). Además, para asegurar que no se pierda ninguna temporización de la animación, también se fusionan los retardos de tiempo de los dos fotogramas. Por ejemplo…

  magick moving_hole_oplus.gif -coalesce -layers RemoveDups  gif:- |\
     gif_anim_montage - moving_hole_oplus_rmdups_frames.gif

[IM Output]

Y ahora tenemos de nuevo nuestra forma fusionada original de la animación. Para otro método de eliminar los fotogramas extra, consulta el método «[RemoveZero](#removezero)» más abajo.

División de las actualizaciones de fotograma - actualizar por separado dos cambios distantes

Como has visto con la duplicación de fotogramas, separando el «borrado de píxeles» de la superposición de píxeles nuevos podemos reducir el tamaño total de la superposición de un solo fotograma. Sin embargo, esta animación sigue produciendo algunas superposiciones muy grandes, formadas en su mayor parte por píxeles que en realidad no cambian de un fotograma al siguiente. Es decir, la superposición de fotograma principal solo actualiza dos zonas bastante pequeñas que están bastante alejadas entre sí, produciendo así una única imagen de superposición grande. En lugar de intentar actualizar ambos cambios a la vez, incluyendo además todos esos píxeles que no cambian entre las dos zonas, actualizamos cada zona por separado. Es decir, dividimos la actualización de fotograma en dos fases, una para cada una de las zonas separadas que cambian. En este caso, podemos rellenar primero el agujero antiguo y después crear el nuevo agujero como una actualización aparte. En realidad, no importa (salvo posiblemente por los descartes) cuál de los dos cambios separados se haga en qué orden, pero conviene ser lógico al respecto. También puede ser que un cambio sea más fácil de crear que otro. Por ejemplo, aquí inserto fotogramas extra para rellenar el agujero antiguo como una actualización aparte del «cavado» del nuevo agujero. Este es el fotograma intermedio más fácil de generar, así como el orden de acciones más lógico. Por supuesto, no necesitas hacer esto para el último fotograma, ya que ese fotograma simplemente se descarta antes de que la animación vuelva a empezar el bucle. | |

  magick moving_hole.gif \
          \( +antialias -size 100x100 -delay 0 xc:SkyBlue \
             -fill DodgerBlue -draw 'circle 50,50 15,25' \
             -fill RoyalBlue  -draw 'circle 50,50 30,25' \) \
          \( +clone \) -insert 1 \( +clone \) -insert 3  +swap \
          -set dispose background  moving_hole_split.gif
  gif_anim_montage x2 moving_hole_split.gif moving_hole_split_frames.gif

[IM Output]
[IM Output]
Recuerda que el fotograma intermedio añadido es distinto de los fotogramas que rodean y que se muestran al usuario (los que tienen un retardo de tiempo distinto de cero). Esto no es una simple «duplicación de fotogramas», sino la separación de dos cambios pequeños y distantes. Esta adición de fotogramas intermedios no es un paso sencillo que pueda automatizarse. Aunque es posible que pudiera desarrollarse una heurística inteligente para generar estos fotogramas intermedios, no siempre es evidente qué debe hacerse, ni siquiera si debe hacerse. Si quieres intentar generar una heurística así, escríbeme por correo. Así que probemos una optimización de fotogramas estándar tras añadir estos fotogramas extra… | |

  magick moving_hole_split.gif \
               -layers OptimizeFrame     moving_hole_split_opt.gif
  gif_anim_montage x2 moving_hole_split_opt.gif \
                      moving_hole_split_opt_frames.gif

[IM Output]
[IM Output]
La adición de estos «fotogramas intermedios de retardo cero» permite que esta animación se optimice mejor por fotogramas que la animación original sin optimizar, produciendo una animación de [IM Text] bytes. Sin embargo, para este caso concreto no es tan bueno como usar una técnica automática de duplicación de fotogramas (consulta el método de capas «OptimizePlus» más arriba). No obstante, añadir «fotogramas intermedios de retardo cero» no impide que apliques también esa técnica de «duplicación de fotogramas»… | |

  magick moving_hole_split.gif \
               -layers OptimizePlus moving_hole_split_oplus.gif
  gif_anim_montage x2 moving_hole_split_oplus.gif \
                      moving_hole_split_oplus_frames.gif

[IM Output]
[IM Output]
Esta animación tiene ahora dos «fotogramas intermedios de retardo cero» extra por cada actualización de fotograma. El primero rellena el agujero antiguo; el segundo borra una zona que contendrá píxeles transparentes, antes de que finalmente se restauren los píxeles que no debían haberse borrado. El resultado es la optimización de fotogramas más óptima posible para esta animación problemática concreta, con un tamaño de archivo final de [IM Text] bytes. Es decir, ¡nuestra animación de 4 fotogramas se hizo más pequeña añadiendo 6 fotogramas extra de retardo de tiempo cero! Más del doble del número original de fotogramas. ¡Raro pero cierto! Por supuesto, también estaría bien que los programas de animación GIF reconocieran realmente los fotogramas intermedios de retardo cero por lo que son: actualizaciones intermedias entre los fotogramas reales de la animación. Pero aun así, cuando las actualizaciones están muy separadas y son muy pequeñas, la ligera pausa causada por los fotogramas extra rara vez es visible.
Por supuesto, si las dos partes separadas de la animación en realidad no están relacionadas, entonces no necesitan estar sincronizadas en el tiempo. Otra alternativa es que, en lugar de añadir fotogramas extra, dividas la animación en dos animaciones completamente separadas que puedas mostrar juntas en una página web. Consulta Dividir una animación. Sin embargo, esta animación en particular no puede dividirse en animaciones separadas e independientes en el tiempo. Primero, los cambios distantes deben sincronizarse en el tiempo; y segundo, las cuatro zonas que cambian se solapan tanto en dirección horizontal como vertical. Esto significa que una simple «tabla» de HTML no puede volver a unir las subanimaciones en un todo completo, sin algún tipo de truco con CSS. ¿Puedes demostrar que me equivoco? FUTURE: referencia a un mejor ejemplo de animación de «dos objetos distantes», en «Tratamiento de animaciones», por ejemplo con dos objetos que se mueven por separado.

Eliminar fotogramas de retardo cero - quitar actualizaciones intermedias

Por supuesto, a veces no te interesan estos fotogramas intermedios añadidos, o quieres eliminarlos de una animación, dejando solo los fotogramas que realmente se mostrarán al usuario durante algún tiempo. No puedes simplemente fusionar (coalesce) la animación y usar el método «[RemoveDups](#removedups)», ya que no todos los «fotogramas intermedios» son similares a los fotogramas que los rodean y, por tanto, no son duplicados. No obstante, como este tipo de fotogramas tiene un retardo de tiempo cero, puedes usar otro método especial de «[-layers](https://imagemagick.org/command-line-options/#layers)», «**RemoveZero**», que eliminará cualquier fotograma con un retardo de tiempo cero. Este mismo método también eliminará los fotogramas añadidos mediante las técnicas de duplicación de fotogramas y «[OptimizePlus](#optimizeplus)». Por ejemplo…

  magick moving_hole_split_oplus.gif -coalesce -layers RemoveZero gif:- |\
     gif_anim_montage - moving_hole_split_rmzero_frames.gif

[IM Output]

Lo cual, de nuevo, devuelve la animación solo a los fotogramas visibles por el usuario, simplificando la animación. Por supuesto, tras eliminar los fotogramas intermedios de retardo cero, es muy difícil volver a añadirlos, ya que la información de cambio contenida se pierde. En consecuencia, puede que la animación no se optimice muy bien por fotogramas después. Al fin y al cabo, la optimización es uno de los principales propósitos de esos fotogramas.

Resultados y resumen de la optimización de fotogramas

Resumamos nuestras optimizaciones de la animación del agujero móvil…

[IM Text]

Como puedes ver, usando un tratamiento complejo de fotogramas, con la ayuda de IM y algo de intervención humana, pudimos optimizar por fotogramas la animación del «agujero móvil» hasta casi la mitad de su tamaño original, aunque con algo menos del triple del número de fotogramas del original. Por supuesto, los resultados pueden variar mucho de una animación a otra, pero las técnicas que usamos para la optimización de fotogramas son las mismas. Solo hace falta un poco de cuidado y previsión, en lo que los humanos somos buenos y los ordenadores no. | _Aquí está el punto: IM no solo debería tener en cuenta el número de píxeles del conjunto de fotogramas que está examinando, sino también el tamaño total del fotograma extra añadido, y quizá los resultados de compresión globales obtenidos, al tomar la decisión sobre cómo optimizar la imagen por fotogramas.

Por otro lado, IM tampoco considera el ahorro resultante en el número de píxeles que pueda producirse más allá de los fotogramas directamente implicados. Es decir, los tamaños de fotogramas posteriores también pueden ser menores como resultado de la duplicación de fotogramas o del método de descarte usado. Esto es especialmente cierto cuando hay que elegir si usar el método de «descarte de imagen anterior», que puede tener reducciones sustanciales del recuento de píxeles más adelante en una secuencia de animación, en lugar de inmediatamente en el fotograma siguiente. Una buena elección aquí a menudo requiere la intervención humana.

Por eso no puedo garantizar que IM vaya a producir las mejores elecciones de optimización para una animación concreta. Sin embargo, desde luego lo intenta de buena manera, sin usar recursión, para tomar esa decisión. Es decir, usando solo los recuentos de píxeles inmediatos para su decisión.

Un algoritmo recursivo, uno que toma una decisión y luego ve cuál es el mejor tamaño final de la animación que resulta de esa decisión (incluyendo elecciones recursivas más adelante), podría producir una mejor optimización garantizada. Sin embargo, también podría ser un operador extremadamente lento y, para una animación grande, podría tardar años en tomar la decisión final. También tendría que incluir las elecciones de optimización de la compresión, ya que estas podrían afectar al resultado final. Dicho de otro modo, aunque un algoritmo así podría garantizar la mejor optimización, lo hace con un fuerte coste computacional.

Por supuesto, un ser humano con un conocimiento íntimo de lo que la animación intenta lograr, por lo general lo hará mejor en animaciones complejas, como viste más arriba con la división de las actualizaciones de fotograma.

Si te gustaría intentar crear un operador recursivo de optimización de GIF, adelante. Ayudaré en todo lo que pueda. Superaría a prácticamente cualquier otro programa de optimización de GIF del mercado. Además, la mayoría de los desarrolladores de animaciones GIF probablemente estarían muy agradecidos por tus esfuerzos (económicamente)._
---|---


Tratamiento de la semitransparencia

El formato de archivo GIF no permite el uso de píxeles semitransparentes (consulta Transparencia booleana de GIF). Esto es un hecho y, antes de poder optimizar correctamente una animación, o incluso de guardarla en formato GIF, debes tratar cualquier píxel semitransparente que pueda haber, de una manera adecuada para la animación. De forma predeterminada, si no tratas estos píxeles, IM usará un umbral del 50 % para convertirlos en totalmente transparentes o totalmente opacos. Sin embargo, esa puede no ser la mejor manera de abordar el problema, sobre todo en imágenes que contienen grandes zonas de píxeles semitransparentes, como los efectos de sombra. Por ejemplo, yo quería crear una animación de teletransporte de los Asgard de Stargate que pudiera tomar casi cualquier subimagen como objeto teletransportado.

  magick -channel RGBA -fill white \
          \( medical.gif -repage 100x100+34+65 -coalesce -set delay 200 \) \
          \( +clone -motion-blur 0x20+90 -blur 0x3 -colorize 100% \
                +clone -colorize 30%  +swap  -composite  -set delay 10  \) \
          \( +clone -roll +0-20 -blur 0x3 -colorize 30% \
             -motion-blur 0x15+90 -motion-blur 0x15-90 -set delay 10 \) \
          \( +clone -colorize 30% \
             -motion-blur 0x30+90 -blur 0x5 -crop +0+10\! \) \
          \( +clone -motion-blur 0x50+90 -blur 0x2 -crop +0+20\! \) \
          \( +page -size 100x100 xc:none -set delay 200 \) \
          -set dispose background -coalesce   -loop 0     teleport.miff
  gif_anim_montage teleport.miff teleport_frames.png

[IM Output]

Dejé la animación a propósito en el formato de archivo interno MIFF: de IM, ya que esto garantiza que la imagen original se conserve sin modificaciones, y usé el formato de archivo PNG: para mostrar los fotogramas, de modo que puedas ver todos los píxeles semitransparentes que contiene. Esto no solo es importante para las animaciones con píxeles semitransparentes, sino también para las que tienen muchos colores. Una vez que la secuencia de imágenes se ha guardado en GIF, tus posibilidades de generar una buena optimización del color pasan de buenas a difíciles. Bien, tengo una secuencia de animación. Si intento guardarla directamente como GIF, IM se limitará a aplicar un umbral a todos esos píxeles semitransparentes. |

  magick teleport.miff teleport_thres.gif
  gif_anim_montage teleport_thres.gif teleport_thres_frames.gif

[IM Output]

[IM Output]

El resultado no se parece en nada a lo que queríamos. El tratamiento de transparencia predeterminado del 50 % hace que la animación parezca un «huevo» que se encoge. Desde luego, no es lo que quiero lograr con esta animación. Si este tipo de tratamiento de la transparencia es aceptable, esta es la forma de aplicarlo, antes de continuar con tus otras optimizaciones…

  magick teleport.miff -channel A -threshold 50% +channel \
                 ...haz aquí más procesamiento...       teleport.gif

Una ventaja adicional de usar el método casero anterior es que puedes controlar el nivel del umbral. Por ejemplo, «10%» para eliminar casi todos los píxeles semitransparentes presentes, o «90%» para hacerlos todos opacos. |

  magick teleport.miff -channel A -threshold 90% +channel teleport_thres90.gif
  gif_anim_montage teleport_thres90.gif teleport_thres90_frames.gif

[IM Output]

[IM Output]

Pero aplicar un umbral a animaciones como esta no es una buena solución, ya que estropea de verdad el efecto de transparencia que intento lograr. La mejor solución global para conservar todos los efectos especiales de la animación anterior es simplemente añadir un color de fondo sólido. |

  magick teleport.miff -bordercolor skyblue \
                  -coalesce -border 0 teleport_bgnd.gif
  gif_anim_montage teleport_bgnd.gif teleport_bgnd_frames.gif

[IM Output]

[IM Output]

Esto elimina TODA la transparencia de la animación, pero a costa de que la animación solo funcione sobre un color de fondo concreto. Pero si estás creando la animación para una página web concreta, eso puede ser perfectamente aceptable. No obstante, ten en cuenta que, en imágenes con contornos nítidos, usar un patrón de tramado como este puede producir un contorno «moteado» en los bordes nítidos. Por eso no se recomienda para el caso general. La otra solución es intentar generar algún patrón de píxeles transparentes y opacos para tratar de conservar la semitransparencia de la imagen. Y para esto IM ofrece una amplia gama de opciones de tramado que pueden resolver el problema. FUTURE: algún enlace a una sección por crear sobre el tramado de transparencia, como Cuantización y tramado. Ten en cuenta que la primera solución evidente, usar un tramado monocromo del canal alfa, no es sencilla y probablemente requiera alguna composición multiimagen avanzada para hacerla correctamente. Una solución sencilla es usar una técnica de tramado ordenado por difusión de píxeles, que puede restringirse solo al canal alfa, para eliminar los píxeles semitransparentes. |

  magick teleport.miff -channel A -ordered-dither o8x8  teleport_od.gif
  gif_anim_montage teleport_od.gif teleport_od_frames.gif

[IM Output]

[IM Output]

El resultado es aceptable, pero parece más un objeto que se disuelve que uno que se teletransporta. Usar un semitono producirá un efecto mucho más agradable al hacer más marcado el patrón de transparencia. |

  magick teleport.miff -channel A -ordered-dither h8x8a teleport_htone.gif
  gif_anim_montage teleport_htone.gif teleport_htone_frames.gif

[IM Output]

[IM Output]

Pero para esta animación concreta descubrí que usar un mapa de tramado diseñado por el usuario para producir líneas verticales (a partir de un patrón de tramado de líneas horizontales) produce un efecto que realza la animación de teletransporte a la vez que elimina los píxeles semitransparentes. |

  magick teleport.miff -rotate 90 \
          -channel A -ordered-dither hlines -rotate -90 teleport_lines.gif
  gif_anim_montage teleport_lines.gif teleport_lines_frames.gif

[IM Output]

[IM Output]

Así que, como puedes ver, hay bastantes posibilidades para tratar la semitransparencia en una animación GIF.


Optimización del color

El tratamiento de los píxeles semitransparentes es solo la primera limitación del formato de archivo GIF. La siguiente es el límite de 256 colores por cada tabla de colores de la animación. Se permite tener una tabla de colores distinta para cada fotograma. Esto significa que una sola animación puede tener más de 256 colores. Sin embargo, ni siquiera eso es siempre una buena idea. Si solo quieres un resumen rápido de las opciones de optimización del color disponibles, te sugiero que saltes a los ejemplos de conversión de Vídeo a GIF, donde los problemas de color de una animación se dan en su peor forma.

El problema del color en GIF

Las animaciones GIF en particular tienen problemas para tratar los colores: primero, no permiten colores semitransparentes; luego, tienen un límite de 256 colores por fotograma, o un límite global de 256 colores. Por último, tu mejor optimización de fotogramas no funcionará muy bien a menos que los colores usados para un píxel en un fotograma coincidan también con el mismo color en el fotograma siguiente, cuando esa parte de la imagen NO cambió. Esto puede parecer un problema fácil, pero la reducción de colores es en sí misma un campo extremadamente complejo, que requirió su propia sección completa en los ejemplos de IM. Los problemas de color son, de hecho, la razón por la que la mayoría de las animaciones GIF que encuentras en la World Wide Web son de tipo dibujo animado o tienen muy mal aspecto. Especialmente si se han redimensionado a partir de una versión más grande de la animación. En Redimensionar animaciones, probablemente se requerirá más esfuerzo en la optimización del color que en el propio proceso de redimensionado. Aquí supondré que tienes la fuente original de la animación. Pero eso no siempre es posible, así que si estás optimizando una animación GIF modificada, puede que se necesite algo de precaución adicional. No obstante, si tienes una animación con demasiados colores, lo primero que hay que recordar es…

No guardes directamente en formato GIF,
usa el formato de archivo MIFF O imágenes PNG separadas.

En cuanto guardas en GIF, has perdido el control de tus esfuerzos de optimización del color de GIF, y probablemente tendrás una animación GIF con muy mal aspecto que no se optimizará muy bien usando las distintas técnicas de optimización de fotogramas.

La animación «speed» - una animación con demasiados colores

Primero necesitamos generar una animación GIF con un número enorme de colores, para poder probar de verdad los problemas que implica la optimización del color. | |

  magick -dispose none -channel RGBA \
          \( medical.gif -repage 100x60+5+14  -coalesce -set delay 100 \) \
          \( medical.gif -repage 100x44+34+6  -coalesce -set delay 10 \
             -motion-blur 0x12+0  -motion-blur 0x12+180 -wave -8x200 \) \
          \( medical.gif -repage 100x60+63+14 -coalesce -set delay 100 \) \
          \( medical.gif -repage 100x44+34+6  -coalesce -set delay 10 \
             -motion-blur 0x12+0  -motion-blur 0x12+180 -wave +8x200 \) \
          null: \( +page  -size 120x15 xc:SkyBlue xc:RoyalBlue \
                   -size 120x70 gradient:SkyBlue-RoyalBlue \
                   +swap -append -blur 0x3 -background white -rotate -25 \
                \) -gravity center -compose DstOver -layers Composite \
          -loop 0   speed.miff

  magick  speed.miff  speed.gif
  gif_anim_montage  speed.gif  speed_frames.gif

[IM Output]
[IM Output]
Fíjate en que no guardé la animación directamente en formato GIF, sino que la guardé primero en un archivo de formato MIFF, «[speed.miff](../static/img/anim_opt/speed.miff)». Esto conserva todos los aspectos de la animación creada (o modificada) originalmente, incluidos los metadatos de GIF, los retardos de temporización, así como todos los colores de la imagen sin distorsión. Solo tras conservar la animación original, convertí directamente la animación original a formato GIF. De ese modo podía mostrar lo que el código anterior pretende lograr y por qué lo llamé «speed». Esto se hizo también para proporcionar una animación GIF de referencia para su estudio y posterior comparación. Así que veamos varios detalles de nuestra animación original…

  magick identify -format "Number of Frames: %n\n" speed.miff | head -1

[IM Text]

  magick identify -format "Colors in Frame %p: %k\n"  speed.miff

[IM Text]

  magick speed.miff +append  -format "Total Number of Colors: %k"  info:

[IM Text]

Como puedes ver, cada imagen de la animación tiene un número muy grande de colores. No solo cada fotograma tiene un número de colores distinto, sino que el primer y el tercer fotograma son muy similares en cuanto al color, aunque no exactamente iguales. Sin embargo, como el formato de archivo GIF solo puede guardar un máximo de 256 colores por fotograma, cuando ImageMagick guardó esto en formato GIF lo hizo de la manera más rápida y tonta posible… Redujo el número de colores de cada fotograma de la animación (un proceso llamado cuantización de colores)…

  magick identify -format "Colors in Frame %p: %k\n"  speed.gif
  magick speed.gif +append  -format "Total Number of Colors: %k"  info:

[IM Text]

Como el número reducido de colores de cada fotograma es ligeramente distinto, IM también necesitó suministrar un mapa de colores separado para cada fotograma de la animación. Esto significa que el archivo GIF tiene una «tabla de colores global» (como siempre la tiene), pero también tres «tablas de colores locales» separadas. El comando «magick identify» no puede decirte cuántas tablas de colores locales tiene un archivo GIF, ya que esa información es demasiado específica del formato y no es importante para el procesamiento de imágenes que IM hace normalmente. Sin embargo, el programa más específico «[Giftrans](http://www.ict.griffith.edu.au/anthony/software/#giftrans)» sí puede decirte cuántas tablas de colores locales de bajo nivel se usaron…

  giftrans -L speed.gif 2>&1 | grep -c "Local Color Table:"

[IM Text]

Como puedes ver, esta animación tiene [IM Text] tablas de colores locales, una menos que el número de fotogramas presentes en la imagen, justo como predije. No solo cada fotograma tiene un conjunto distinto de colores, sino también un patrón de colores ligeramente distinto (el patrón de tramado de la imagen), como se describe en Problemas con los tramados por corrección de error. Normalmente, este comportamiento predeterminado de la cuantización de colores y el tramado de IM es muy bueno y perfectamente adecuado para imágenes, especialmente fotos de la vida real. De hecho, los fotogramas individuales de una animación por lo general se ven estupendos. Todos los problemas surgen cuando luego intentamos encadenar esos fotogramas reducidos individualmente en una única secuencia de animación.

¿Optimizar fotogramas antes que el color?

Como viste más arriba, guardar una animación directamente en formato GIF funciona, pero obtendrás bastantes diferencias de color de un fotograma al siguiente, lo cual es malo para la posterior optimización de fotogramas (como verás más adelante). Para evitar que las diferencias de color causen tales problemas, puedes hacer la optimización de fotogramas antes de guardar la animación, evitando así las diferencias de color introducidas de un fotograma a otro. Pero ten cuidado, porque hacer la optimización de fotogramas antes de reducir el color cambia la dinámica de la reducción de colores. A menudo aparecerán menos de las zonas estáticas e inmóviles en el subfotograma optimizado, lo que significa que la cuantización de colores de ese fotograma puede dar menos importancia a esos colores y, por tanto, menos colores.

Optimización del color difusa

Sin embargo, a veces no tienes acceso a la animación original antes de que se guardara en formato GIF. Esto es especialmente cierto si descargaste la animación original de la WWW. Eso significa que ya tienes una animación con todas esas distorsiones de color de GIF presentes, lo que produce problemas en las optimizaciones posteriores. Ahora bien, como se usa un conjunto de colores ligeramente distinto de un fotograma al siguiente, y un patrón de píxeles distinto para cada fotograma de la animación, cada fotograma puede considerarse una imagen completamente distinta. Por ejemplo, comparemos el primer y el tercer fotograma, que comparten gran parte de la misma imagen de fondo… |

  magick compare  speed.gif'[0,2]' speed_compare.gif

[IM Output]
Las zonas rojas del ejemplo anterior muestran dos zonas cuadradas sólidas de las áreas que son distintas, justo como cabría esperar. Pero también muestra bandas de diferencias de color que perfilan el fondo de los dos fotogramas. Estas representan el patrón de tramado «agitado» a lo largo de los bordes del degradado de fondo, donde se usaron píxeles de color distinto para representar exactamente el mismo fondo. Este fue además el par de fotogramas que mostró menos perturbaciones del fondo causadas por usar distintos conjuntos de colores y patrones de tramado. Las diferencias reales entre fotogramas consecutivos son mucho peores, produciendo una diferencia casi de un rojo sólido. | _Las diferencias de imagen como esta también son un problema si tus imágenes de origen se almacenaron usando el formato de imagen JPEG. Este formato usa un método de compresión con pérdida que (incluso al 100 % de calidad) causa ligeras diferencias de color en las imágenes. Sin embargo, las diferencias suelen quedar confinadas a un halo alrededor de las zonas reales de diferencia, en lugar de extenderse por toda la imagen.

Lo único que puedo decir es: evita las imágenes JPEG para su uso en animaciones, a menos que pienses usar una única imagen como imagen de fondo estática para TODOS tus fotogramas._
---|---
Como tantos píxeles de la animación son distintos de un fotograma al siguiente, no es de extrañar que, cuando intentamos optimizar por fotogramas la animación, no obtengamos ninguna optimización en absoluto…

  magick speed.gif  -layers OptimizeFrame  speed_opt2.gif
  gif_anim_montage  speed_opt2.gif  speed_opt2_frames.gif

[IM Output]

No obstante, la mayoría de las diferencias de color de píxeles entre las partes que no cambian de los fotogramas de la animación son en realidad bastante pequeñas. No habría sido una reducción de colores muy buena si no fuera así. Eso significa que, pidiendo a IM que relaje un poco sus comparaciones de color, puedes pedirle que ignore las diferencias de color menores. Esto se hace fijando un factor de tolerancia (fuzz) adecuado.

  magick speed.gif  -fuzz 5%  -layers OptimizeFrame  speed_opt3.gif
  gif_anim_montage speed_opt3.gif speed_opt3_frames.gif

[IM Output]

Como puedes ver, con la adición de un pequeño factor de tolerancia (fuzz), IM ignorará ahora los píxeles que solo difieren ligeramente, produciendo una optimización de fotogramas razonable. Cuánto factor de tolerancia necesites depende de cuánta dificultad tuvo IM al reducir el color de las imágenes originales. En este caso no mucha, así que solo se necesitó un factor muy pequeño. Si un factor de tolerancia pequeño produce un resultado aceptable, basta con fijarlo para tu optimización de fotogramas y tu optimización de la transparencia. Solo recuerda que aún tienes una tabla de colores separada para cada fotograma de la que ocuparte, que es el siguiente punto de discusión. Ten en cuenta también que la optimización de fotogramas decidió usar un «descarte anterior» para el segundo fotograma. Es decir, tras mostrar el segundo fotograma, devuelve la imagen al descarte del fotograma anterior (la primera imagen) antes de superponer. Esto produjo un tamaño de imagen de superposición menor que si no se usara ningún descarte en toda la animación. Si solo quisieras una simple animación de superposición, usando únicamente el descarte None en toda ella, podrías haber usado en su lugar el antiguo operador Deconstruct (también conocido como Layers CompareAny) para generarla.

  magick speed.gif  -fuzz 5%  -deconstruct  speed_opt4.gif
  gif_anim_montage speed_opt4.gif speed_opt4_frames.gif

[IM Output]

Generar una tabla de colores global única

Ahora bien, como todos y cada uno de los fotogramas tienen un conjunto de colores distinto, IM se vio obligado a guardar la imagen con una tabla de colores separada para cada fotograma: una global para el primer fotograma y 3 tablas de colores locales para los fotogramas posteriores. Por ejemplo, aquí usé el sencillísimo programa «[Giftrans](http://www.ict.griffith.edu.au/anthony/software/#giftrans)» para informar de cuántas tablas de colores de fotograma se crearon.

  giftrans -L speed.gif 2>&1 | grep -c "Local Color Table:"

[IM Text]

Para una animación totalmente fusionada (o de tipo tira de película), tener tablas de colores separadas para cada fotograma está perfectamente bien y es razonable, y en tales situaciones esto no es un problema. Es decir, para pases de diapositivas de imágenes muy distintas, las tablas de colores separadas producirán el resultado de mejor aspecto. Por eso este es el comportamiento normal de funcionamiento de IM. Sin embargo, todas estas tablas de colores extra son muy costosas, ya que cada tabla de colores puede usar mucho espacio. Hasta 768 bytes (256 colores × 3 bytes por color, o 3/4 de kilobyte) por cada fotograma de la imagen. No solo eso, sino que la compresión de GIF no comprime estas tablas de colores, ¡solo los datos de píxeles! Si dedicar tanto espacio de archivo a tablas de colores separadas es un problema, especialmente para una imagen que no cambia mucho de color, como ocurre con la mayoría de las animaciones GIF, entonces puedes hacer que IM use únicamente la tabla de colores global necesaria y no añada ninguna tabla de colores local. --- Para eliminar los mapas de colores locales, todas las imágenes deben pasar a ser de tipo palette y todas usar la misma paleta. En la línea de comandos puedes hacerlo fijando un «-map image» para definir la paleta del comando. No puedes usar -colors, ya que eso opera sobre imágenes individuales. La solución de la línea de comandos es una opción especial «[+map](https://imagemagick.org/command-line-options/#map)», que hace una reducción global de colores a una paleta común que se añade a todas las imágenes. TEN EN CUENTA que cualquier cambio en la imagen probablemente invalidará la paleta, así que, aunque la reducción de colores debe hacerse ANTES de hacer las optimizaciones de fotogramas o de compresión de GIF, la paleta común debe ser lo último, justo antes de guardar. Si «[+map](https://imagemagick.org/command-line-options/#map)» no necesita reducir el número de colores de una imagen, no lo hará ni tramará los colores, solo añadirá una paleta común a todas las imágenes. --- IM puede generar una única tabla de colores global si todos los fotogramas usan la misma paleta de colores. En IM, las paletas de colores solo se asignan a una imagen leyéndolas de un formato de imagen que use tal paleta, o asignándole una mediante el operador de reducción de colores «[-map](https://imagemagick.org/command-line-options/#map)». Consulta Tramado con mapa de colores predefinido para más detalle. Una manera de generar esta única tabla de colores es simplemente «[-append](https://imagemagick.org/command-line-options/#append)» (concatenar) todos los fotogramas juntos y luego usar el comando «[-colors](https://imagemagick.org/command-line-options/#colors)» para reducir el número de colores a un conjunto mínimo (menos de 256, o más pequeño si quieres una tabla de colores aún menor). La tabla de colores resultante puede entonces aplicarse a la imagen original usando «[-map](https://imagemagick.org/command-line-options/#map)». Por ejemplo, aquí reduzco la imagen a un único conjunto de 64 colores. Esto usa el especial registro en memoria MPR para asignar el mapa de colores generado al comando «[-map](https://imagemagick.org/command-line-options/#map)». |

  magick speed.gif \
          \( -clone 0--1 -background none +append \
              -quantize transparent  -colors 63  -unique-colors \
             -write mpr:cmap    +delete \) \
          -map mpr:cmap      speed_cmap.gif

[IM Output]
Ahora, si examinas la animación resultante usando «[Giftrans](http://www.ict.griffith.edu.au/anthony/software/#giftrans)», verás que la imagen usa ahora una única tabla de colores «global», en lugar de una tabla de colores separada para cada fotograma. | _Uso un «[-background](https://imagemagick.org/command-line-options/#background)» de color «None» antes de concatenar las imágenes, lo que te permite usar esto en animaciones no fusionadas y no tener la posibilidad de añadir colores extra innecesarios.

El ajuste especial «transparent» del espacio de color «[-quantize](https://imagemagick.org/command-line-options/#quantize)» se usó para asegurar que IM no intente generar colores semitransparentes en su mapa de colores. Algo inútil, ya que estamos guardando el resultado en GIF, que no puede tratar la semitransparencia.

Por último, reduzco a 63 colores, para dejar espacio para un color transparente. Algunas animaciones necesitan transparencia, mientras que otras (como esta) pueden seguir necesitándola más adelante para la optimización de la compresión._
---|---
Para facilitar esto, IM también proporciona una opción especial «[+map](https://imagemagick.org/command-line-options/#map)» que generará un mapa de colores común (de 256 colores) sobre todos los fotogramas, aplicándolo globalmente. Esto es mucho más sencillo que el método casero anterior. |

  magick speed.miff  -alpha off +map   speed_map.gif

[IM Output]
Esto produjo [IM Text] tablas de colores «locales» (o extra no deseadas) en la imagen resultante. Usaré la versión de tabla de colores única de la animación para las siguientes secciones de optimización, aunque en realidad podrías hacer esto en cualquier punto de tus optimizaciones de animación, y especialmente antes del guardado final. Como resultado de la optimización de la tabla de colores, la animación que ocupaba [IM Text] bytes en nuestro GIF convertido directamente, ocupa ahora [IM Text] bytes, tras usar el operador «[+map](https://imagemagick.org/command-line-options/#map)». Cuantos más fotogramas (y «tablas de colores locales») tenga una animación, mayor será el ahorro. Ahora bien, como cualquier modificación de una animación por lo general elimina la paleta guardada de cada una de las imágenes, es importante que el operador «[+map](https://imagemagick.org/command-line-options/#map)» sea la última operación antes de guardar la animación en GIF. Recuerda:

La eliminación de los mapas de colores locales debe ser la última optimización, antes de guardar en formato GIF.

Tramado ordenado, eliminar el «ruido»

En construcción

Ten en cuenta, no obstante, que en todas las técnicas que hemos visto hasta ahora puede haber un patrón de tramado que cambia de una superposición a otra. Una agitación de los píxeles que puede parecerse al ruido («nieve») de la televisión.

... número reducido de colores ...

Con una optimización de fotogramas de una zona inmóvil más pequeña, puedes incluso obtener zonas rectangulares de ruido que se ven aún peor. ... Tramado ordenado ... Por ahora, consulta el más práctico y menos detallado Vídeo a GIF, resumen de optimización.


Optimización de la compresión

Una vez que tienes tu animación guardada en formato GIF, tras tratar los píxeles semitransparentes y usar las optimizaciones de color y de fotogramas, también puedes conseguir algunas reducciones menores del tamaño de archivo adaptándote al algoritmo de compresión de GIF. La compresión LZW o la compresión por longitud de series (RLE) que puede usar el formato de archivo GIF comprimirá mejor si encuentra zonas más grandes de color constante, o secuencias de píxeles que se repiten una y otra vez.

Optimización de la transparencia

Como viste en la optimización de fotogramas, una imagen superpuesta a menudo se limitará a repetir lo que ya se está mostrando. Es decir, superpone los mismos píxeles de color que ya están presentes después de aplicar los métodos de descarte de GIF. Pero ¿para qué molestarse en repetir esos píxeles? Si ya estás usando transparencia en una imagen, tienes disponible un color de píxel transparente. Pero al convertir esas zonas en transparencia, obtienes zonas más grandes de píxeles transparentes uniformes. Eso puede comprimirse mejor que usar una mezcla de colores distintos, necesarios para igualar la misma zona que se superpone. Por ejemplo, aquí tienes una sencilla animación de superposición optimizada por fotogramas [IM Output] [IM Output]
Usemos ahora el método «**OptimizeTransparency**» de «[-layers](https://imagemagick.org/command-line-options/#layers)» (añadido en IM v6.3.4-4) para reemplazar por transparencia cualquier píxel que no cambie el resultado mostrado.
  magick bunny_bgnd.gif -layers OptimizeTransparency \
                                    +map   bunny_bgnd_opttrans.gif
  gif_anim_montage bunny_bgnd_opttrans.gif bunny_bgnd_opttrans_frames.gif

[IM Output]
[IM Output]
Como puedes ver, los subfotogramas tienen ahora grandes zonas transparentes, que no afectan a la animación resultante final. Las zonas que necesitan cambiar los píxeles siguen superponiéndose, pero las zonas que no cambian se han hecho transparentes. Eso incluye también el interior del objeto que se anima, dejando «agujeros» de aspecto más bien horrible. Como las zonas más grandes de color transparente constante (en teoría) comprimen mejor, la animación «desordenada» resultante es mucho más pequeña, reduciendo el tamaño de archivo del resultado optimizado por fotogramas de [IM Text] bytes a [IM Text] bytes. Este es un ahorro bastante grande para un esfuerzo muy pequeño. Ten en cuenta que el método de optimización no necesitaba ser una animación fusionada, y que el tamaño de los subfotogramas se deja sin cambiar, para conservar las necesidades de descarte de este fotograma y de los posteriores. Por eso, cualquier ahorro es solo en términos de mejores relaciones de compresión para el mismo número de píxeles de la animación, y no en el número real de píxeles guardados en el archivo. Por tanto, debe hacerse después de haber completado cualquier optimización de fotogramas necesaria, como uno de tus pasos de optimización finales.

FUTURE: enlace a un «eliminar el fondo» de una animación

Por supuesto, como en la mayoría de los demás métodos de «[-layers](https://imagemagick.org/command-line-options/#layers)» (de comparación u optimización), puedes especificar un factor de tolerancia (fuzz) para ajustar «cuán similares» se consideran los colores. Eso te permite tratar animaciones que estaban mal tramadas en color, aunque si hubieras estudiado la optimización del color anterior, no deberías tener ese problema. La herramienta gratuita de GIF animado «**[InterGIF](http://utter.chaos.org.uk/~pdh/software/intergif.htm)**» también ofrece este mismo tipo de optimización de compresión por transparencia mostrada arriba, pero sin la capacidad de admitir además un «factor de tolerancia» para hacer transparentes también los cambios de color «próximos». No la recomiendo, salvo como alternativa cuando IM no esté disponible.

Optimización LZW - (no IM)

Algunas aplicaciones pueden optimizar aún más la relación de compresión de las imágenes de una animación para hacerlas todavía más pequeñas. Sin embargo, hacerlo requiere un conocimiento especializado de la compresión LZW que el formato de archivo de imagen GIF suele usar. Básicamente, si una secuencia concreta de píxeles ya ha sido tratada por el algoritmo de compresión LZW, no se molestará en convertirlos en píxeles transparentes, ya que hacerlo no mejoraría la compresión de la imagen. Suena raro, pero funciona. Por desgracia, ImageMagick no hará esto, ya que es un proceso tan complejo que requiere una gran cantidad de habilidad y recursos para conseguir una heurística razonablemente buena que produzca un buen resultado en el caso general. No obstante, sí puedo darte un ejemplo práctico de esta técnica usando la aplicación «[Gifsicle](http://www.lcdf.org/gifsicle/)» en su nivel de optimización más alto, «-O2». |

  gifsicle -O2 bunny_bgnd.gif -o bunny_bgnd_lzw_gifsicle.gif
  gif_anim_montage bunny_bgnd_lzw_gifsicle.gif bunny_bgnd_lzw_frames.gif

[IM Output]

[IM Output]

La optimización de la compresión LZW redujo la imagen de [IM Text] bytes con la simple optimización de la transparencia, a [IM Text] bytes con «Gifsicle». No es una gran mejora. Sin embargo, el aspecto más importante es que, aunque la optimización LZW convirtió en transparencia los píxeles que no cambian (como hicimos usando la optimización de la transparencia anterior), no cambió una secuencia de píxeles que ya se había visto. Es decir, solo se cambiaron los grupos de píxeles que no se habían repetido ya dentro de la animación, ya que esos píxeles (presumiblemente) ya comprimirían bien usando los patrones de compresión LZW. Ten en cuenta que la selección de qué píxeles deben hacerse transparentes, para generar patrones de píxeles repetidos, es muy compleja y difícil, y puede incluso depender de la implementación exacta de LZW. Es una heurística, no un algoritmo perfectamente predecible. Por eso, distintos programas producirán por lo general resultados distintos según la imagen concreta que se comprima. Un programa puede producir una mejor relación de compresión para una imagen, y otro puede ser mejor para una imagen distinta.

Optimización LZW con pérdida - (no IM)

Otro método de mejora de la compresión consiste en la ligera modificación de los propios colores de los píxeles hacia «coincidencias de color próximas», a fin de aumentar la repetición de las referencias de color en la imagen. Un patrón repetido naturalmente comprime mejor y, por tanto, puede producir relaciones de compresión más altas. Una bifurcación de la anterior aplicación «Gifsicle», conocida como giflossy, también genera un programa «gifsicle», pero uno con la opción de modificar la imagen de formas menores (es «con pérdida») para reducir el tamaño de las imágenes GIF, especialmente en las animaciones, mucho más. | |

  gifsicle -O3 --lossy=80 bunny_bgnd.gif -o bunny_bgnd_giflossy.gif
  gif_anim_montage bunny_bgnd_giflossy.gif bunny_bgnd_lossy_frames.gif

[IM Output]

[IM Output]


Creado: 22 de marzo de 2007 (subdivisión de «animation»)
Actualizado: 23 de abril de 2007
Autor: Anthony Thyssen, Anthony.Thyssen@gmail.com
Ejemplos generados con: [version image]
URL: https://usage.imagemagick.org/anim_opt/

Esto produjo un tamaño de [IM Text], que es una asombrosa reducción de tamaño de 1/3. Por desgracia, este método implica cambiar la imagen resultante y, por tanto, la optimización es con pérdida, ya que puede perder información de color sutil. En el lado positivo, te permite comprimir los fotogramas individuales, en lugar de la optimización entre fotogramas. Por ejemplo, aquí generé una imagen de diferencia de la anterior compresión LZW sin pérdida frente a una compresión LZW con pérdida. |

  magick compare bunny_bgnd_lossy_frames.gif bunny_bgnd_lzw_frames.gif \
          bunny_bgnd_diff_frames.gif

[IM Output]

Como puedes ver, casi todas las modificaciones de color estaban en la imagen de fondo original de la «hierba», en lugar del conejo de dibujos animados. Básicamente, modificó las cosas lo justo para marcar una gran diferencia, y para esta imagen no una diferencia realmente perceptible en el aspecto. Por supuesto, la cuantización de colores y el tramado es en sí misma una operación con pérdida y normalmente se necesita de todos modos, así que usar un método de compresión con pérdida para imágenes GIF y animaciones GIF no se considera muy malo. Para otro ejemplo de un algoritmo así, patentado para su uso por Photoshop, consulta la patente estadounidense 7031540 - Transformación para aumentar la compresibilidad Lempel-Ziv de las imágenes con una distorsión visual mínima. Es una lectura densa, pero detalla los métodos que usa para lograr una mejor compresión.

Optimización LZW con tramado ordenado

Como el proceso de tramado suele ser un proceso con más pérdida que las optimizaciones LZW, una solución mejor puede ser intentar introducir los patrones repetibles como parte del proceso de tramado. Eso puede lograrse usando el tramado ordenado para producir tales patrones y, por tanto, ahorros de compresión LZW mucho más fuertes que todos los métodos de optimización LZW anteriores. Como ventaja añadida, también puede mejorar la optimización de fotogramas de animaciones de la vida real con fondos estáticos. Eso sería especialmente cierto si limpias artificialmente el fondo para que se convierta en un fondo estático que no cambia. Por supuesto, la optimización de la compresión por tramado ordenado solo funciona para imágenes que no han sido tramadas ni optimizadas en color de otro modo previamente. Por eso, solo funciona para animaciones que aún no han sido optimizadas para el formato de imagen GIF. Además, actualmente el tramado ordenado de IM solo funciona para una paleta de colores uniforme. IM todavía no tiene una implementación de tramado ordenado con paleta de «mejor color» o «proporcionada por el usuario», aunque he visto programas que usan un algoritmo así para paletas de colores muy limitadas (y fijas). ¿Conoces algún algoritmo así? Para un ejemplo práctico del uso del tramado ordenado para mejorar la optimización de la compresión LZW, consulta Vídeo con tramado ordenado.

Otras optimizaciones LZW

También pueden lograrse otras mejoras en la optimización LZW mediante otras reordenaciones del «patrón de tramado» de la imagen. Y algunas herramientas de GIF pueden hacer exactamente eso. Sin embargo, cualquier optimización de ese tipo siempre debería revisarse con el ojo humano antes de aprobarse, ya que a veces puede producirse un cambio de color sutil pero malo.

Resumen de la optimización de la compresión

Aquí tienes un resumen completo de los tamaños de archivo finales conseguidos usando optimizaciones de compresión.

[IM Text]

Como puedes ver, usando la muy compleja optimización LZW solo se consiguió una ligera mejora en el tamaño final de la animación, frente a la optimización de la transparencia integrada. Sin embargo, los resultados también son muy variables entre los numerosos programas de aplicación de optimización de GIF disponibles, y la animación concreta que se optimiza. Si de verdad necesitas exprimir hasta el último byte de un tamaño de archivo, entonces una optimización LZW puede ser justo lo que necesitas. Y si de verdad necesitas los mejores resultados, deberías probar varios programas distintos (y, por tanto, implementaciones heurísticas) para ver cuál comprime mejor tu animación concreta, incluyendo qué otras funciones de optimización ofrecen. Normalmente, una optimización de la transparencia es suficiente para la mayoría de los propósitos. La optimización LZW solo produce un resultado ligeramente mejor, generando un ahorro muy menor en cuanto a tamaños de transmisión por red, más que en tamaño de almacenamiento en disco, ya que este último usa «trozos» o «bloques» de almacenamiento más grandes. Por eso, considero que la optimización LZW es excesiva, y no creo que merezca el esfuerzo ni el dinero (la mayoría de estas herramientas se venden comercialmente). | _Por desgracia, he comprobado que estos optimizadores de GIF no tratan muy bien TODOS los tipos de animaciones preoptimizadas.

Por ejemplo, mis pruebas muestran que «[Gifsicle](http://www.lcdf.org/gifsicle/)» no logra tratar una animación que ya estaba optimizada usando una técnica de «descarte de fondo».

Por otro lado, comprobé que «[InterGIF](http://www.chaos.org.uk/~pdh/software/intergif.htm)» no trata animaciones que ya han sido optimizadas para usar un lienzo inicial y una técnica de «descartes anteriores». También está limitado al uso de la optimización de la transparencia, que IM ahora ofrece.

Por eso te recomiendo que no mezcles utilidades de optimización de GIF alimentando la salida de una utilidad a otra. Al menos no sin antes fusionar la animación para eliminar cualquier optimización de fotogramas anterior.

IM, Gifsicle e InterGIF, todos ofrecen tales opciones de fusión para eliminar sus propias optimizaciones, aunque no puedo garantizar que las aplicaciones que no son IM fusionen TODAS las animaciones correctamente. IM sí lo hará.

_
---|---
Como no puedes usar estos programas de forma fiable con las avanzadas técnicas de optimización de fotogramas de IM (que seleccionan y cambian automáticamente entre distintas técnicas de descarte de GIF), a menudo he comprobado que IM produce con frecuencia un resultado global mejor que limitarse a usar estos optimizadores de compresión LZW. También te sugiero que fusiones (Coalesce) de nuevo el resultado después y compares sus fotogramas con la animación original sin optimizar, para asegurarte de que el programa que no es IM no haya estropeado de algún modo la animación por completo (consulta la nota anterior). Créeme, lo he visto ocurrir, y los scripts deberían comprobar dos veces que las animaciones siguen siendo válidas.
Otro tutorial (que usa herramientas de Windows) sobre este tipo de optimización es WebReference Frame Optimation. Ten en cuenta que el sitio tiene mal el nombre, ya que trata sobre la optimización de la compresión.


Optimizaciones menores

Hay algunas otras técnicas de optimización que puedes usar con las animaciones GIF, que a menudo son tan obvias que se pasan por alto.

  • Eliminar los comentarios de GIF.
    Muchas animaciones GIF tienen añadido un comentario de texto grande. A menudo, los editores gráficos los añadieron automáticamente como una forma de publicidad. Por ejemplo, «Gimp» añade de forma predeterminada «Created with The GIMP» a las imágenes. Si el comentario no es necesario, es un desperdicio de espacio. Elimínalos añadiendo un operador «[+set](https://imagemagick.org/command-line-options/#set) comment» al comando «magick» de IM antes de guardar el GIF. Ten en cuenta, no obstante, que si el comentario es un aviso de derechos de autor, puede no ser buena idea eliminarlo por razones legales.
  • Reducir el número de colores.
    Si la animación se ve bien con menos colores, usa una tabla de colores más pequeña. Las tablas de colores son siempre una potencia de dos, así que si puedes usar menos de 32 colores, eso es mucho más pequeño que usar 256 colores. Esto es especialmente importante, ya que las tablas de colores no se comprimen con la compresión LZW usada para los datos de imagen de GIF. Además, usar menos colores producirá por lo general una mejor compresión LZW, ya que se encuentran más secuencias de píxeles comunes. Sin embargo, esto no siempre es así, ya que el tramado de color (debido a la reducción de colores) también puede empeorar la compresión. Desactivar el tramado o usar un tramado ordenado puede ser importante aquí.
  • Reducir a la mitad el número de fotogramas visibles para el usuario.
    Si puedes tolerar una animación menos fluida, entonces reducir a la mitad el número total de fotogramas puede producir una buena mejora en el tamaño de archivo final. Por supuesto, no obtienes un archivo de la mitad de tamaño, y la calidad de la animación se reduce. Pero puede producir una reducción muy grande del tamaño de archivo.
  • Recortar/redimensionar la animación.
    Un tamaño de imagen menor significa un tamaño de archivo menor. Así que si no necesitas una animación grande, no uses una animación grande. Una pequeña miniatura para representar una animación o un vídeo más grande a menudo es preferible, en un listado, a la cosa real.
  • Compresiones alternativas.
    Si no piensas usar la animación como animación, es decir, solo quieres almacenarla, ¡desactiva la compresión LZW y comprime TODO el archivo con «gzip» o «bzip2» para almacenarlo! El resultado es mucho más pequeño, aunque requiere que los servidores web den las indicaciones correctas de «contenido» y «compresión» a los navegadores para que sea directamente utilizable por los navegadores cliente. El servidor web «Apache» no hace esto de forma predeterminada, pero se puede configurar para que lo haga. Mejor todavía, archiva todo el directorio de animaciones sin comprimir en un único archivo, para una compresión de almacenamiento aún mejor.

Si tienes alguna otra idea de optimización, házmelo saber.


Otras fuentes de información sobre la optimización de GIF

Con lo anterior se completan los distintos métodos y técnicas básicos para tratar animaciones. Sin embargo, para formar una imagen completa, deberías continuar en la siguiente página de los ejemplos de IM, que detalla técnicas para tratar problemas reales con animaciones de imágenes reales. Además, muchas de las técnicas anteriores se demuestran en los ejemplos prácticos de Optimización de vídeo a GIF. También te recomiendo que leas a fondo sobre la cuantización de colores si de verdad te tomas en serio el trabajo con animaciones GIF, ya que la reducción de colores suele ser la clave de un buen tratamiento de las animaciones GIF. Otras fuentes útiles de técnicas de optimización de animaciones GIF que he encontrado en la WWW incluyen…

Escríbeme por correo si crees que tienes una página que debería listar aquí. Solo añadiré páginas de contenido útil, así que no hay garantías de que añada tu enlace.