⚠️ 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_mods/index.html).

ImageMagick Ejemplos -- Modificaciones de animaciones

ImageMagick Ejemplos: prefacio e índice
Modificaciones sencillas de animaciones

Esta página contiene ejemplos prácticos de trabajo con animaciones GIF. Se recomienda encarecidamente leer y comprender los Fundamentos de las animaciones y, al menos, el manejo general de la Optimización de animaciones GIF antes de intentar comprender estos ejemplos.


Modificaciones sencillas de animaciones

Primero, un punto importante

NO guarde directamente en GIF las animaciones intermedias cuyo procesamiento aún no haya terminado, en especial las imágenes a las que todavía no haya aplicado ningún tipo de manejo de la semitransparencia u optimización de color. Si cometiera el gran error de guardar en GIF, no haría más que empeorar la animación resultante, ya que IM habría realizado una cuantización de color automática para reducir el número de colores presentes y así ajustar las imágenes al limitado formato GIF. No solo eso, sino que procesa cada fotograma de forma completamente independiente del resto, lo que produce selecciones de color y patrones de tramado distintos. Es decir, eso vuelve mucho más difícil cualquier procesamiento posterior, en particular cualquier optimización de fotogramas. Esto es especialmente importante para las animaciones GIF redimensionadas, o aquellas a las que haya añadido una superposición o un fondo multicolor, ya que esto puede añadir muchos colores adicionales. Puede usar el formato interno de IM, MIFF, como formato de archivo temporal si desea trabajar una animación por pasos, o usar imágenes individuales en formato PNG para cada uno de los fotogramas que esté editando. Simplemente no haga el guardado final a GIF a menos que esté seguro de que no tendrá problemas de color. Lo repito...

No use GIF como formato de archivo intermedio; use MIFF o imágenes PNG.

A partir de la versión 6.2.6 de IM, puede "[-annotate](https://imagemagick.org/command-line-options/#annotate)" una animación, de forma similar a la detallada en Anotar sobre las imágenes, simplemente haciéndolo. Por ejemplo, aquí anotamos la animación previous dispose creada en los Fundamentos de las animaciones. |

  magick canvas_prev.gif -gravity center \
          -fill black     -annotate +1+1 "Copyright" \
          -fill white     -annotate +0+0 "Copyright" \
          annotate.gif
  gif_anim_montage annotate.gif annotate_frames.gif

[IM Output]

[IM Output]

La razón por la que esto funciona es que "[-annotate](https://imagemagick.org/command-line-options/#annotate)" posiciona el texto en relación con el lienzo virtual de una imagen, y no en relación con los datos reales de la imagen. Por ello, la posición del texto en cada fotograma es correcta para una imagen animada. Sin embargo, antes de la versión 6.2.6, "[-annotate](https://imagemagick.org/command-line-options/#annotate)", como muchos otros operadores de imagen, posicionaba la información y las superposiciones en relación con la imagen real, e ignoraba cualquier desplazamiento de página o lienzo virtual que pudiera tener un subfotograma. Una advertencia: dibujar sobre una animación de esta manera, sin antes combinarla (coalesce), puede provocar algunos efectos inusuales, debido al esquema de optimización ya existente de la animación (vea el siguiente grupo de ejemplos). Por ello (y como verá) se recomienda eliminar primero cualquier optimización de fotogramas y transparencia existente combinándola (coalesce).

Dibujo - modificar una animación combinada (coalesce)

Ahora bien, mientras que "[-annotate](https://imagemagick.org/command-line-options/#annotate)" coloca el texto en relación con el lienzo virtual de cada fotograma, muchas otras operaciones de imagen no lo hacen. Esto incluye todas las operaciones "[-draw](https://imagemagick.org/command-line-options/#draw)", que solo dibujan en relación con la imagen real e ignoran por completo cualquier desplazamiento que pueda tener sobre un lienzo más grande. Por ejemplo, aquí dibujamos un elegante círculo verde cerca de la esquina superior izquierda de la animación previous dispose. |

  magick canvas_prev.gif -fill LimeGreen -stroke SeaGreen \
          -draw 'circle 35,35 20,30'  draw_circle_fail.gif
  gif_anim_montage draw_circle_fail.gif draw_circle_fail_frames.gif

[IM Output]

[IM Output]

Pues bien, como puede ver, "[-draw](https://imagemagick.org/command-line-options/#draw)" dibujó el círculo en relación con la «imagen real», en lugar del lienzo virtual (página) más grande del que forma parte la imagen. El resultado es, como es típico en este tipo de situaciones... un desastre. La solución sencilla a esto es combinar (coalesce) primero la animación, antes de dibujar, y luego volver a optimizar la animación GIF después. Vea Optimización de animaciones para más detalles. |

  magick canvas_prev.gif -coalesce \
          -fill LimeGreen -stroke SeaGreen -draw 'circle 35,35 20,30' \
          -layers Optimize  draw_circle.gif
  gif_anim_montage draw_circle.gif draw_circle_frames.gif

[IM Output]

[IM Output]

Observe cómo el optimizador de animaciones de IM decidió en realidad simplemente no sobrescribir la parte sobre la que se dibujó. Esto es de hecho más óptimo que si hubiera dibujado sobre las propias imágenes de los subfotogramas. Este método le permite superponer cualquier tipo de anotación, aviso de copyright o marca de agua que desee. Por supuesto, puede que necesite usar la técnica especial de composición de capas para superponer realmente una imagen sobre cada fotograma de una animación. Si llega a dominarlo bien, incluso puede recurrir a la fusión de animaciones para superponer un aviso de copyright animado sobre su animación. | _Aunque esta técnica de «combinar y optimizar» funciona con la mayoría de las operaciones que involucran animaciones, especialmente con el optimizador de IM, hay algunas operaciones que realizan cambios tan drásticos en las imágenes —como grandes cambios de color, sombreados y semitransparencia— que la animación resultante no se optimiza muy bien.

Por ejemplo, casi cualquier operación "[-resize](https://imagemagick.org/command-line-options/#resize)" es probable que produzca una animación que después se optimice muy mal debido a los grandes cambios de color. Vea Redimensionar animaciones más abajo para conocer soluciones a esto.

_
---|---

Fotograma a fotograma - modificar un fotograma a la vez

Usando los operadores de lista o secuencia de imágenes de IM puede modificar cada fotograma de la animación por separado. El truco consiste en extraer cada fotograma entre paréntesis, modificarlo y luego reemplazar la imagen original por la versión modificada. Por ejemplo, aquí añadimos texto como marca de agua de copyright a la animación, como una animación en sí misma, lo que la hace aún más difícil de quitar. Para no destruir por completo la animación, también usé colores semitransparentes. |

  magick canvas_prev.gif -coalesce -gravity center \
          -font Ravie -pointsize 24 -fill '#FFF8' -stroke '#0008' \
          \( -clone 0 -annotate 0 'This'        \) -swap 0 +delete \
          \( -clone 1 -annotate 0 'This'        \) -swap 1 +delete \
          \( -clone 2 -annotate 0 'image'       \) -swap 2 +delete \
          \( -clone 3 -annotate 0 'is'          \) -swap 3 +delete \
          \( -clone 4 -annotate 0 'Copy\nright' \) -swap 4 +delete \
          -layers OptimizeFrame   frame_mod.gif
  gif_anim_montage frame_mod.gif frame_mod_frames.gif

[IM Output]

[IM Output]

Observe el uso de los paréntesis para limitar el efecto de la operación "[-annotate](https://imagemagick.org/command-line-options/#annotate)" a un simple «clon» de un fotograma de la animación. La imagen modificada se devuelve luego a su posición correcta en la secuencia de imágenes usando los operadores Swap y Delete. El uso de un solo número en el operador "[-swap](https://imagemagick.org/command-line-options/#swap)" se añadió en IM v6.3.4-3. Antes de esto, necesitaría especificar "-swap 3" como "-swap -1,3" para que funcionara correctamente.
Esta técnica de modificar fotogramas individuales será probablemente una de las técnicas más importantes que encontrará al manipular animaciones de imágenes. También notará que en realidad añadí el mismo texto tanto a la primera como a la segunda imagen. La primera imagen de la animación anterior es un fotograma intermedio de retardo cero, que se usa para definir el fondo del resto de esta animación. Es decir, pasa tan rápido que normalmente no es visible para los usuarios, ni se pretende que lo sea. Por lo tanto, los dos primeros fotogramas reales de la animación anterior deben considerarse como un único fotograma visible, en lugar de dos fotogramas separados. El fotograma con un retardo de tiempo distinto de cero es el último fotograma de una secuencia de fotogramas «de visualización». De forma similar, para otras animaciones que corren rápido, puede que necesite modificar varios fotogramas para que su cambio sea visible durante un periodo de tiempo apreciable. Esto no es un problema para una anotación estática dibujada sobre todos los fotogramas (vea el ejemplo anterior de anotación). Esto nos lleva a un punto importante sobre las animaciones GIF.

Estudie una animación antes de intentar modificarla.
Puede marcar una GRAN diferencia en el resultado final.

Recortar - limitar el área de la animación

IM se ha esforzado por hacer que la operación de imagen "[-crop](https://imagemagick.org/command-line-options/#crop)" funcione correctamente en relación con el lienzo virtual de una imagen, en lugar de la imagen real (a partir de la versión 6.1.1 de IM). Esto, a su vez, le permite hacer cosas que antes no eran directamente posibles. Por ejemplo, recortar las imágenes de una animación GIF y que siga funcionando como se espera para todas las animaciones. |

  magick canvas_prev.gif -crop 50x50+3+30  cropped.gif
  gif_anim_montage cropped.gif cropped_frames.gif

[IM Output]

[IM Output]
Como puede ver, el recorte funcionó, igual que lo haría al recortar una sola imagen, preservando el desplazamiento y el tamaño de página apropiados, de modo que los datos de la imagen siguen estando posicionados correctamente, aunque el área implicada se haya reducido. ¡Como puede ver, esto no cambió el tamaño global del lienzo virtual! | No use "[+repage](https://imagemagick.org/command-line-options/#repage)" para eliminar los desplazamientos de recorte de una animación GIF optimizada por fotogramas. Hacerlo también eliminaría los desplazamientos de fotograma necesarios que posicionan los subfotogramas en el lienzo virtual, y de los que los fotogramas posteriores pueden depender para animar correctamente.
---|---
Sin embargo, la operación "[-crop](https://imagemagick.org/command-line-options/#crop)" anterior produjo un mensaje de advertencia...

[IM Text]

Como el recorte de uno de los fotogramas de la animación quedó fuera de la imagen de superposición del subfotograma usada para ese fotograma. Es decir, un fotograma no actualizó el área que se recortó de la animación. Como resultado, ese fotograma ya no contiene ninguna imagen real. Para compensarlo, IM no solo produce un mensaje de advertencia, sino que genera una «imagen perdida» especial como marcador de posición en la animación, para mantener todo en orden y preservar cualquier método de «retardo» o «descarte» asociado a ese fotograma. Puede dejar ese marcador de posición, o corregirlo como quiera. En este caso, la «imagen perdida» es necesaria para que la animación corra como se espera. No obstante, si se generan varias imágenes perdidas consecutivas, probablemente pueda fusionarlas en una sola imagen perdida usando el método '[RemoveDups](anim_opt.html#removedups)' de "[-layers](https://imagemagick.org/command-line-options/#layers)". Aun así, se recomienda precaución y estudiar la animación. (Vea Dividir una animación más abajo para un ejemplo más detallado de esto.)

Recortar también el lienzo - recorte por viewport de la animación

Igual que un recorte normal preservaba el lienzo virtual de las imágenes originales, también lo hizo un recorte de una animación. Probablemente esto no sea la intención en este caso. Debido a esto, en la versión 6.2.4-5 de IM, se añadió una bandera especial '!' al argumento de "[-crop](https://imagemagick.org/command-line-options/#crop)". Esta bandera hará que el recorte no solo recorte los fotogramas individuales de la imagen, sino que también ajuste la información de página o lienzo de la imagen a esa misma área. Esto se conoce como «recorte por viewport», ya que el resultado será como si estuviera mirando la imagen a través de una «ventana» o «viewport» del tamaño y la posición del argumento de recorte. No solo se establece el tamaño del lienzo virtual al tamaño del área de recorte, sino que también se ajusta el desplazamiento de cada fotograma de la animación para mantener las cosas correctas. (Vea Recorte por viewport con ajustes de lienzo/página). Por ejemplo, repitamos el recorte anterior, pero recortando también la información del lienzo con la bandera '!'... |

  magick canvas_prev.gif -quiet -crop 50x50+3+30\!  crop_viewport.gif
  gif_anim_montage crop_viewport.gif crop_viewport_frames.gif

[IM Output]

[IM Output]
| El carácter '!' tiene un significado especial para algunos shells de UNIX, como "csh", y debe escaparse con una barra invertida, incluso cuando se coloca entre comillas. IM ignora las barras invertidas en los argumentos de geometría, así que no hace daño escaparlo siempre.
---|---
Como puede ver, el resultado se parece más a lo que probablemente quería lograr al recortar una imagen animada. Note que incluí un ajuste "[-quiet](https://imagemagick.org/command-line-options/#quiet)" para pedirle a IM que no diera el mensaje de advertencia sobre la imagen perdida que generamos en el intento de recorte anterior. Esto se recomienda siempre que se recorten animaciones, ya que la advertencia en realidad no aplica. Note que un recorte por viewport también le permitirá aumentar el área del lienzo o incluso reposicionar todo dentro del lienzo. Sin embargo, es peligroso, ya que cualquier imagen que quede parcial o totalmente fuera del área de recorte se reducirá para mostrar solo la parte de la imagen que aparece dentro de esa área. Una última advertencia. Al usar un «recorte por viewport», las imágenes de los fotogramas se mueven en la dirección negativa al desplazamiento dado para el «viewport». Esto puede parecer ilógico, a menos que recuerde que el desplazamiento del operador de recorte es la posición del viewport, y no un reposicionamiento directo de las propias imágenes.

Recorte de límites - corrección automática del tamaño del lienzo

Como ocurre con las operaciones anteriores, recortar (trim) una animación puede ser delicado. Si la animación consiste en una simple animación de fotogramas borrados, entonces puede recortar una animación simplemente calculando los límites máximos de todos los fotogramas individuales dentro de la animación. A partir de IM v6.3.4-8 puede hacer esto muy fácilmente usando un método de capa 'TrimBounds'.

  magick anim_bgnd.gif -layers TrimBounds anim_trim_bounds.gif

[IM Output] [IM Output]

Para los usuarios de versiones de IM anteriores a esta, todavía puede hacer lo mismo, pero solo en un proceso de dos pasos (que además realiza otro procesamiento no deseado). Para hacerlo, usaría una fusión de capas (Layers Merge) para fusionar todos los fotogramas de una animación en una sola capa, y luego haría que IM informara del tamaño y el desplazamiento de esa capa...

  magick anim_bgnd.gif -layers merge -format '%wx%h%X%Y' info:

[IM Text]

Ahora que conoce los límites de todos los fotogramas, puede simplemente aplicar un recorte por viewport a toda la animación a este tamaño.

  magick anim_bgnd.gif -crop 89x77+5+10! anim_trim_crop.gif

[IM Output] [IM Output]

Si además quiere recortar un fondo estático de una animación, lo mejor es eliminar el primer fotograma de una animación optimizada por fotogramas antes de usar el paso de fusión de capas (Layers Merge). Luego puede usar los límites obtenidos para el recorte por viewport sobre la animación original.

Reposicionar fotogramas

Una operación similar y relacionada es el operador de «repage relativo». Este añadirá el desplazamiento dado a todas las capas de subfotograma individuales de la animación, permitiéndole ajustar sus posiciones en relación con todo el lienzo. Para hacer que una operación "[-repage](https://imagemagick.org/command-line-options/#repage)" sea relativa, también añade una bandera '!' a su argumento. Por ejemplo, aquí desplazamos el segundo y los fotogramas posteriores de una animación 30 píxeles hacia abajo y a la derecha, devolviendo el primer fotograma de «fondo» a su posición normal '+0+0'. |

  magick canvas_prev.gif -repage 0x0+30+30\! \
           \( -clone 0 -repage +0+0 \) -swap 0,-1 +delete \
           repage_offset.gif

  magick identify repage_offset.gif

[IM Output]
| [IM Text]


| La animación anterior fallará (mostrará solo los dos primeros fotogramas) en Windows Internet Explorer versión 8. Esto ocurre cada vez que un fotograma intenta dibujar una imagen más allá de los límites del lienzo de la animación.
---|---
Note que ninguna de las imágenes ha sido «recortada» ni reducida. Solo se han cambiado sus posiciones, en relación con la imagen de fondo original, incluso si la imagen se movió «fuera del lienzo». Si lo desea, también puede expandir el lienzo para que coincida con estos nuevos límites, ya sea ajustando el tamaño del lienzo directamente... |

  magick repage_offset.gif -repage 130x130  repage_canvas.gif

[IM Output]
Usando el método de capa de recorte de límites puede expandir automáticamente los límites de la animación lo justo para incluir las imágenes que ahora quedaban «fuera de límites»... |

  magick repage_offset.gif -layers TrimBounds repage_bounds.gif

[IM Output]
| _Usar "[-repage](https://imagemagick.org/command-line-options/#repage)" para mover imágenes hacia la izquierda o hacia arriba, especialmente con un lienzo pequeño, es probable que falle en las animaciones GIF. Este formato básicamente no puede usar un desplazamiento de imagen negativo.

Para eso, podría ser mejor aplicar también un «recorte por viewport», o usar «trim bounds» para desplazar todos los desplazamientos hacia un lienzo positivo más grande. Cualquiera de los dos métodos garantizará un desplazamiento positivo para todos los fotogramas de la imagen.

Los formatos PNG y MNG pueden manejar desplazamientos negativos, pero muchos navegadores web y otros programas pueden no entender tales desplazamientos, produciendo efectos extraños. Una versión del navegador web "Firefox", por ejemplo, produce imágenes extremadamente grandes al intentar mostrar un PNG con un desplazamiento negativo._
---|---

Invertir animaciones - hacer que las animaciones corran hacia atrás o en ciclo

A partir de IM v6.3.3, se añadió el operador de secuencia de imágenes "[-reverse](https://imagemagick.org/command-line-options/#reverse)" (vea el operador Reverse para más detalles). Esto le permite invertir muy fácilmente el orden de una secuencia de animación combinada (coalesced). Por ejemplo, aquí hago que una animación de «k dibujada a mano» se «desdibuje». |

  magick script_k.gif -coalesce -reverse \
          -quiet -layers OptimizePlus  -loop 0 reversed.gif

[IM Output]
Tuve que volver a añadir la opción "[-loop](https://imagemagick.org/command-line-options/#loop)" a lo anterior, ya que esta debe adjuntarse a la primera imagen, ¡que ahora es la última imagen! El resultado también podría beneficiarse de algunos ajustes de temporización, pero como puede ver, ¡ahora «desdibuja» la letra! Asegúrese de "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)" la secuencia de imágenes antes de invertirla, ya que cualquier optimización de fotogramas presente depende del orden de las imágenes. Es mejor eliminar primero esas optimizaciones.

Ciclos de patrulla - ir y volver entre dos extremos

Una técnica similar consiste en añadir al final de la animación los fotogramas en orden invertido, de modo que la animación resultante haga un ciclo entre el primer y el último fotograma de la animación original. Es un poco como un guardia que patrulla entre dos puntos, y se llama «ciclo de patrulla». Aquí uso el operador Duplicate (añadido en IM v6.6.8-7) para generar los fotogramas adicionales (invertidos). |

  magick script_k.gif -coalesce   -duplicate 1,-2-1 \
          -quiet -layers OptimizePlus  -loop 0 patrol_cycle.gif

[IM Output]
Note que no copié simplemente todas las imágenes de la animación, sino que omití copiar la primera y la última imagen de la secuencia original. Si hubiera copiado todas las imágenes, la primera y la última aparecerían durante el doble del tiempo esperado, y harían el archivo de animación más grande de lo necesario. Aun así, debe volver a tener cuidado con los fotogramas intermedios de retardo cero al principio y al final de la animación, ya que estos pueden provocar problemas inesperados. Básicamente, no haga esto sin estudiar primero la animación, o se estará buscando problemas. Además, para permitir una mejor optimización del resultado, puede que incluso necesite añadir algunos fotogramas intermedios de retardo cero adicionales entre los ciclos de avance e inversión, para mejorar la optimización. Estos fotogramas adicionales probablemente no se proporcionaron en la optimización original de la animación, ya que toda la animación normalmente se reinicia cuando hace bucle. Vea Dividir actualizaciones de fotogramas para más detalles de cómo estos fotogramas adicionales ayudan a optimizar y mejorar la animación. Aquí hay un método más antiguo que usa el operador Clone para generar fotogramas duplicados. |

  magick script_k.gif -coalesce \( -clone -2-1 \) \
          -quiet -layers OptimizePlus  -loop 0 patrol_cycle_2.gif

[IM Output]

Morphing de color - transición animada entre dos imágenes

El operador "[-morph](https://imagemagick.org/command-line-options/#morph)" es un operador especialmente interesante. Toma una lista de imágenes e inserta fotogramas adicionales entre ellas, de modo que se produce un suave cambio de color de una imagen a la siguiente. Sin embargo, este operador no es un verdadero «morph», ya que solo modifica el color de los píxeles creando una secuencia de imágenes mezcladas. Un verdadero «morph» de estilo cinematográfico también implica distorsión de la imagen para transformar el contorno del objeto de una imagen en los objetos de la otra. Por ejemplo, aquí creo un ciclo de patrulla usando un morph de color para generar los fotogramas adicionales entre la imagen de la rosa y su forma volteada. |

  magick -delay 20 rose: \( +clone -flip \)  -morph 5 \
          -duplicate 1,-2-1  rose_flip.gif

[IM Output]
Esto no es particularmente bueno, ya que todas las imágenes tienen el mismo retardo. El resultado es que la animación nunca parece «descansar» o pausarse entre los dos extremos del ciclo. Una mejor solución sería tener una pausa en la original y en su forma «volteada». Sin embargo, eso requiere que ajuste los retardos de las imágenes originales para que sean distintos de los de las imágenes del morph. |

  magick rose: \( +clone -flip \)  -morph 5 -set delay 10 \
          \( -clone 0 -set delay 240 \) -swap 0 +delete \
          \( +clone   -set delay 240 \) +swap   +delete \
          -duplicate 1,-2-1 rose_flip_pause.gif

[IM Output]
Como puede ver, los retardos de temporización pueden volverse muy importantes para generar buenas animaciones, permitiendo que la animación «descanse» justo en los puntos adecuados. A partir de IM v6.6.9 puede establecer el retardo usando escapes de porcentaje FX que calculan en función del índice de la imagen. Aquí la expresión FX dice que use un retardo de 10 si el índice de la imagen no es el primero (t=0) ni el último (t=n-1); de lo contrario, use un valor mayor. |

  magick rose: \( +clone -flip \)  -morph 5 \
          -set delay '%[fx:(t>0&&t<n-1)?10:240]' \
          -duplicate 1,-2-1    rose_flip_anim.gif

[IM Output]
Para toda una gama de métodos diferentes de «morphing» o de hacer una «transición» de una imagen a otra, vea los scripts de shell de ImageMagick "[transitions](http://www.fmwconcepts.com/imagemagick/transitions/)" y "[fxtransitions](http://www.fmwconcepts.com/imagemagick/fxtransitions/)" de Fred Weinhaus. La página de ejemplos incluye el algoritmo básico que el script usa para generar la animación.

Morphing de redimensionado - cambio de tamaño animado

El operador de morph de color en realidad no solo hace mezcla de color entre dos imágenes, sino que también redimensiona la imagen al mismo tiempo. Por ejemplo, aquí uso "[-morph](https://imagemagick.org/command-line-options/#morph)" sobre dos imágenes que tienen tamaños diferentes, e incluso relaciones de aspecto diferentes. |

  magick rose: medical.gif -morph 10 \
          -layers TrimBounds -set dispose previous -coalesce \
          -background black -alpha remove \
          -set delay '%[fx:(t>0&&t<n-1)?10:60]' \
          -duplicate 1,-2-1  -loop 0  morph_resize.gif

[IM Output]
Solo la primera línea hace el morph de redimensionado. Si observara las imágenes reales, ¡cada fotograma tendrá un tamaño diferente! Las dos líneas siguientes «rellenan» las imágenes para que tengan el mismo tamaño, rellenando las partes no usadas con negro. En concreto, las operaciones están diseñadas para que el orden de la imagen no importe. El resto solo sirve para configurar un ciclo de patrulla y los retardos de temporización asociados. El «redimensionado» solo se realiza desde la esquina superior izquierda. Al momento de escribir esto, el operador de morph de color no entiende los desplazamientos de capa, ni ningún otro morphing espacial (morphing distorsionado). Por ello, si quiere que el redimensionado quede centrado, puede que necesite usar técnicas mucho más complejas mostradas en secciones posteriores. Aquí hay un ejemplo similar, esta vez redimensionando la imagen con una versión más pequeña de la misma imagen (preservando la relación de aspecto)... |

  magick rose: \( +clone -resize 10 \) -morph 10 \
          -layers TrimBounds -set dispose previous -coalesce \
          -background black -alpha remove \
          -set delay '%[fx:(t>0&&t<n-1)?10:60]' \
          -duplicate 1,-2-1  -loop 0  morph_resize_self.gif

[IM Output]
Note que las imágenes «intermedias» son más borrosas de lo que probablemente deberían. Esto se debe a que la imagen más grande no solo se está redimensionando a un tamaño más pequeño, sino que también se está mezclando en color con la imagen más pequeña que fue redimensionada a un tamaño mayor.

Barrido (wipe) - crear un barrido de una imagen a otra

Esto en realidad es muy fácil de hacer. Simplemente superponga «tiras» de la nueva imagen. Estas se generan directamente usando un sencillo recorte en mosaico (Tile Crop). Por ejemplo, aquí «barremos» de una imagen a su versión volteada y, solo por diversión, barremos de vuelta. |

  magick rose: \( -clone 0 -flip -crop 3x0 \) \
                \( -clone 0 -crop 3x0 \) \
                -set delay 10 -loop 0  wipe.gif

[IM Output]
Aquí hay una versión de GeeMack, de los foros de IM, que implementa barridos desde las cuatro direcciones... |

  magick -size 100x60 -delay 100 \
      gradient:green-yellow gradient:blue-purple \
      gradient:orange-white gradient:red-black \
      -write mpr:stack -delete 0--1 \
      \
      mpr:stack'[0]' \( mpr:stack'[1]' -set delay 5 -crop 4x0 \) \
      mpr:stack'[1]' \( mpr:stack'[2]' -set delay 5 -crop 0x4 \) \
      mpr:stack'[2]' \( mpr:stack'[3]' -set delay 5 -crop 4x0 -reverse \) \
      mpr:stack'[3]' \( mpr:stack'[0]' -set delay 5 -crop 0x4 -reverse \) \
      -loop 0 wipe_all.gif

[IM Output]

Distorsiones animadas - distorsionar varias imágenes según el índice de la imagen

Muchos operadores pueden usar escapes de porcentaje en sus argumentos. Esto significa que en realidad puede modificar el operador para que se comporte ligeramente distinto en cada imagen que se procesa. El método consiste en primero duplicar imágenes para crear 30 (o las que quiera) copias idénticas de la imagen de la rosa. Luego modifica cada imagen de forma distinta usando escapes de porcentaje FX para calcular valores de distorsión, basados en el índice de la imagen '%[fx:t]' y el número de imágenes de la lista '%[fx:n]'. Por ejemplo, aquí traslado la imagen una cantidad calculada. |

  magick rose: -duplicate 29  -virtual-pixel tile \
          -distort SRT '0,0 1, 0, %[fx:w*t/n],%[fx:h*t/n]' \
          -set delay 10 -loop 0     rose_diagonal_roll.gif

[IM Output]
Y aquí roto la imagen, según el índice, pero genero una pausa más larga si el índice de la imagen es 0 (la primera imagen). |

  magick rose: -duplicate 29  -virtual-pixel Gray \
          -distort SRT '%[fx:360*t/n]' \
          -set delay '%[fx:t==0?240:10]' -loop 0     rose_rotate.gif

[IM Output]
Note que el índice de la imagen ('t') tiene un valor de '0' a 'n-1', por lo que la fórmula '%[fx:t/n]' tendrá un valor de '0.0' a un valor justo por debajo de '1.0'. Esto es perfecto para una animación repetitiva o cíclica como la anterior, pero puede no ser muy bueno para generar transiciones de una imagen a una nueva imagen. En ese caso, si quiere que el fotograma final tenga un multiplicador de '1.0', use la fórmula '%[fx:t/(n-1)]'. Esto es solo una muestra de lo que ahora se puede hacer fácilmente usando índices de imagen en los cálculos '%[fx:...]'. Imagine lo que es posible con distorsiones más complejas. Sin el uso de cálculos con el índice de imagen, lo anterior habría requerido un bucle de shell externo, para generar cada fotograma individualmente, y un paso aparte para recopilar los fotogramas y formar la animación final. Ejemplos de tales scripts de shell con bucles se dan en Animaciones sencillas de imágenes deformadas, ya que esos operadores no permiten el uso de escapes de porcentaje en sus argumentos. | Antes de IM v6.6.9-0, los escapes de porcentaje y los escapes de porcentaje FX que involucran índices de imagen, como '%p', '%n', '%[fx:t]' y '%[fx:n]', estaban rotos. Normalmente solo devolvían valores poco útiles de '0' o '1', y no el índice y el número reales de imágenes de la secuencia de imágenes actual.
---|---

Añadir una etiqueta - añadir una etiqueta a toda la animación

Como siempre, hay varias maneras de añadir realmente una etiqueta a una imagen. Por ejemplo, para animaciones que tienen un lienzo de fondo inicial, o que solo superponen nuevo color sobre los fotogramas previos, puede simplemente añadir la etiqueta al primer fotograma de la imagen. Los demás fotogramas no la eliminarán. Aquí solo añadimos algo de espacio extra con "[-splice](https://imagemagick.org/command-line-options/#splice)", y "[-annotate](https://imagemagick.org/command-line-options/#annotate)" algo de texto en él. |

  magick canvas_prev.gif \
          \( -clone 0 -coalesce -gravity South -background white \
             -splice 0x18 -annotate 0 'Label First' \) \
          -swap -1,0 +delete   label_first.gif

[IM Output]
Sin embargo, esto solo funciona para algunas animaciones. No funcionaría para una animación de fotogramas borrados común, que borra o reemplaza todos los píxeles después de mostrarse cada fotograma. Para un método más general que funcione con todas las animaciones, necesitamos primero "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)" la animación a la animación combinada (coalesced) no optimizada. Luego podemos añadir la etiqueta a todos y cada uno de los fotogramas combinados de la animación, antes de volver a optimizarla. |

  magick canvas_prev.gif -coalesce \
          -gravity South -background white -splice 0x18 \
          -annotate 0 'A Better Label' \
          -layers Optimize labeled_anim.gif

[IM Output]
En lugar de usar "[-annotate](https://imagemagick.org/command-line-options/#annotate)" para dibujar texto en el espacio extra añadido, puede usar un método de composición (vea las secciones siguientes) para componer una imagen en el espacio añadido. De esa manera puede preparar una etiqueta mucho más elaborada para añadir a la animación. Por supuesto, hacer esto puede causar que algunas animaciones no se optimicen muy bien después, especialmente las animaciones de fotogramas borrados, pero ese es el precio que paga por añadir etiquetas. Una solución para ese tipo de animación es anteponer un «lienzo de fondo inicial» que contenga la etiqueta, como se muestra en la sección que explica las animaciones de fotogramas borrados. Note también que añadir una etiqueta a una animación puede resultar en muchos colores adicionales. Esto podría desbordar los límites de color del GIF, por lo que puede que tenga que estar preparado para optimizar el color de su animación también. Una tarea muy difícil que es mejor evitar si es posible (vea Optimización de color). Esto puede ser un problema para cualquier modificación general de cualquier animación.

Eliminar la transparencia - añadir un fondo de color sólido

Un gran número de animaciones que encuentra en la web tienen un fondo transparente. Estas son muy útiles, ya que puede colocarlas en páginas web sin necesidad de preocuparse por cualquier patrón de fondo que pueda estar presente. Sin embargo, al procesar animaciones, especialmente al aplicar otros operadores de imagen como "[-resize](https://imagemagick.org/command-line-options/#resize)" y "[-blur](https://imagemagick.org/command-line-options/#blur)", una animación así tiene problemas. La solución general es eliminar la transparencia de la imagen, generalmente superponiéndolas de algún modo sobre un color específico, como el color concreto que se usa como fondo de una página web. [IM Output] Por ejemplo, aquí tengo una sencilla animación de superposición transparente de una letra 'K' que se dibuja como por una mano invisible. Como esta animación GIF se dibuja con transparencia, y solo superpone imágenes sobre los fotogramas previos (añadiendo píxeles, nunca quitándolos), una manera sencilla de establecer un color (o imagen) de fondo es añadirlo solo al primer fotograma de la animación. Todos los demás fotogramas contienen un color transparente para el fondo, así que no afectarán al resultado. Aquí usamos el operador Flatten para superponer el primer fotograma de la animación sobre un color de fondo 'LimeGreen'. Podemos usar "[-flatten](https://imagemagick.org/command-line-options/#flatten)" para esto, ya que solo lo aplicamos a una sola imagen, y NO a toda la animación. |

  magick script_k.gif \( -clone 0 -background LimeGreen -flatten \) \
          -swap 0,-1 +delete      script_k_flatten_0.gif

[IM Output]
También es importante notar que el primer fotograma original solo tenía un píxel de tamaño. El operador Flatten no solo coloreó el fondo, sino que también expandió ese fotograma a su tamaño completo. Es decir, «rellenó» el fotograma también. Note, sin embargo, que solo se ha coloreado el primer fotograma de la animación. Este método es preferible, ya que se preserva cualquier optimización (como la fuerte optimización que contiene esta animación). Colorear el primer fotograma no funcionará para todas las animaciones GIF. Solo funciona para animaciones de superposición sencillas. Para un método general de eliminar la transparencia de una animación, necesita primero "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)" la animación, y luego eliminar realmente la transparencia de todos los fotogramas, usando el operador Alpha Remove. Esta vez hagámoslo usando un color de fondo 'Tomato'. |

  magick script_k.gif -coalesce   -background Tomato -alpha remove \
          -layers Optimize   script_k_alpha_rm.gif

[IM Output]
Por supuesto, la optimización resultante puede no ser tan óptima como la original, pero la animación ya no tiene ninguna transparencia. Como efecto secundario adicional, cualquier ajuste de descarte '[Background](anim_basics.html#background)' de la animación se habrá convertido en '[None](anim_basics.html#none)' o '[Previous](anim_basics.html#previous)' por el proceso de optimización de fotogramas, ya que la transparencia ya no es un problema. | Alpha Remove se añadió en IM v6.7.5. Si su versión de IM es más antigua, necesitará usar un método alternativo, como aprovechar un efecto secundario del operador Border. Vea Eliminar la transparencia para detalles de este y otros métodos.
---|---
Un manejo de fondo más complejo, como colocar debajo una imagen o un patrón de fondo, requiere un manejo de animaciones mucho más complejo que las simples modificaciones que hemos visto hasta ahora. Esto es lo que veremos a continuación.


Composición alfa de varias imágenes

El siguiente nivel de manejo de animaciones requiere que sea capaz de componer imágenes estáticas individuales ya sea sobre o bajo una animación existente. Es decir, composición alfa general. Esto se vuelve aún más delicado cuando se fusionan dos conjuntos separados de imágenes. Antes de IM v6.3.3-7, la composición de varias listas solo era posible usando scripts de API especialmente diseñados, o scripts de shell que guardaban y fusionaban fotogramas individuales de la animación. Ninguna de las dos eran técnicas muy agradables, pero era todo lo que se podía hacer. Eso, ahora, ha cambiado.

Dibujar imágenes - dibujar una imagen sobre una lista de imágenes

El operador "[-draw](https://imagemagick.org/command-line-options/#draw)" tiene la capacidad de componer una imagen fuente sobre una lista de imágenes. Es también el único método de composición alfa de varias imágenes que podía usar en el comando "[mogrify](basics.html#mogrify)", o contra varias imágenes, antes de IM v6.3.3-7. La razón por la que esta técnica de composición alfa era tan importante es que le permitía especificar una imagen como un argumento separado de la lista de imágenes actual. Es decir, dentro del lenguaje Magick Vector Graphic entre comillas de "[-draw](https://imagemagick.org/command-line-options/#draw)". Debido a su importancia histórica, mostraré su uso en detalle, especialmente para los usuarios que aún tienen versiones más antiguas de IM. Por ejemplo, aquí superpongo la imagen de la rosa sobre toda la animación. |

  magick canvas_prev.gif -coalesce \
          -gravity NorthEast  -draw 'image over 5,5 0,0 "rose:"' \
          -layers Optimize   draw_over.gif

[IM Output]
Esto le permite componer una imagen fuente externa sobre cada imagen de la secuencia de imágenes actual. Esto es suficiente para la mayoría de los propósitos. Por ejemplo, usando el método de composición '[Dst_Over](compose.html#dstover)' también podría colocar una imagen «bajo» la animación como fondo estático. Por ejemplo, aquí «colocamos debajo» una imagen interna "netscape:", aunque podría haber sido cualquier archivo de imagen externo... |

  magick script_k.gif -coalesce \
              -draw 'image DstOver 0,0 0,0 "netscape:"' \
          -layers Optimize   script_k_netscape.gif

[IM Output]
Note que el tamaño de la animación no ha cambiado, ya que son las imágenes destino las que definen el tamaño final de la composición alfa. Si quisiera crear un lienzo más grande, tendría que ajustar el tamaño y los desplazamientos de la animación apropiadamente para acomodar el fondo. Por ejemplo, usando un repage relativo de la animación antes de combinarla. |

  magick script_k.gif  -repage 100x100+20+20\!   -coalesce \
              -draw 'image DstOver 0,0 0,0 "granite:"' \
          -layers Optimize   script_k_granite.gif

[IM Output]
Además, si quisiera usar una imagen que ya había sido leída, creada o modificada, entonces necesita usar un "MPR: registro de programa en memoria para proporcionarle una «fuente de lectura» de esa imagen. |

  magick -size 53x54 xc:SkyBlue -fill DodgerBlue \
          -draw 'circle 26,27 24,8' -write mpr:bgnd +delete \
          \
          script_k.gif -coalesce \
          -draw 'image DstOver 0,0 0,0 "mpr:bgnd"' \
          -layers Optimize   script_k_mpr_bg.gif

[IM Output]
Eso es, más o menos, el límite de los métodos de composición alfa con Draw. Sin manera de superponer las imágenes de la animación «sobre» una imagen destino de tamaño desconocido, y sin manera de fusionar dos secuencias separadas de varias imágenes. Eso fue así hasta que...

Composición de capas - composición alfa para listas de imágenes

Con IM v6.3.3-7 se añadió el método '**Composite**' de "[-layers](https://imagemagick.org/command-line-options/#layers)", que le permite componer dos conjuntos de imágenes completamente separados. (Para un breve resumen, vea Combinar imágenes en capas, Layer Composite.) Para hacer esto en la línea de comandos, se necesita una imagen marcadora especial '[null:](files.html#null)' para definir dónde termina la primera lista de imágenes destino y comienza la lista de imágenes fuente superpuesta. Pero esa es la única complicación real de este método. Así que probémoslo creando un conjunto de sombras a partir de un conjunto de imágenes, y luego superponiendo la imagen original sobre esas imágenes de sombra... |

  magick script_k.gif -coalesce  coalesced_k.gif

  magick coalesced_k.gif  -background black -shadow 100x3+2+5 \
          -background SkyBlue -alpha remove    shadows_k.gif

  magick shadows_k.gif  null:  coalesced_k.gif \
          -layers Composite          compose_shadow.gif

  gif_anim_montage compose_shadow.gif compose_shadow_frames.gif

[IM Output]
[IM Output]
[IM Output]

[IM Output]

El ejemplo anterior es muy importante, así que lo explicaré en detalle. Primero generamos una versión combinada (coalesced) de nuestra animación para eliminar cualquier optimización que pueda estar presente y dejar la animación lista para un procesamiento serio, sin que ninguna optimización GIF interfiera con el procesamiento. A continuación, creamos una imagen de sombra animada a partir de nuestra animación combinada, y eliminamos la transparencia, ya que GIF no puede manejar sombras semitransparentes. Esta es la animación que queremos añadir «bajo» nuestra animación original. Tiene el mismo número de fotogramas, e incluso las mismas temporizaciones que la animación original. Esta correspondencia es importante, así que no la olvide. Ahora leemos las dos secuencias de animación o capas, pero añadimos un separador de imagen '[null:](files.html#null)' especial entre ellas, para que ImageMagick sepa cuándo termina una secuencia y comienza la siguiente. Este separador de imagen es eliminado automáticamente por la importantísima operación "-layer composite" siguiente. Otras API deberían poder usar «varitas» (Wands) separadas de imágenes, en lugar de una sola secuencia con un separador especial. La composición de capas se realiza entonces como si estas dos animaciones o secuencias de imágenes fueran simplemente una sola imagen, en lugar de una secuencia de varias imágenes. Cada par de imágenes, una destino y una fuente, se componen juntas, generando una secuencia de imágenes fusionada (compuesta). El resultado final es que hemos añadido sombras a nuestra secuencia de animación original, que está lista para las optimizaciones GIF, o simplemente para su uso directo.
Ahora puede hacer todos los pasos anteriores en un solo comando. Sin embargo, no puede simplemente usar "[-clone](https://imagemagick.org/command-line-options/#clone)" para crear una copia de la secuencia original, ya que en realidad no sabemos (ni queremos saber) cuántas imágenes hay en la secuencia. En su lugar, puede usar un "MPR: registro de programa en memoria para guardar toda una lista de imágenes. Es como tomar una instantánea de toda la secuencia de imágenes actualmente en memoria, y luego volver a leerla más tarde. El resultado es un comando como este, aunque usé un color de fondo distinto. |

  magick script_k.gif -coalesce -write mpr:images \
          -background black  -shadow 100x3+2+5 \
          -bordercolor Wheat -border 0 \
          null:    mpr:images    -layers Composite \
          magick composite_shadow.gif

[IM Output]
Esta versión en realidad funciona mejor, ya que no perdimos la información de desplazamiento que genera el operador Shadow (los GIF no pueden guardar un desplazamiento negativo, así que lo reinicia a cero). Podríamos corregir eso en lo anterior usando el formato de archivo MIFF para las imágenes intermedias en lugar de GIF o, como verá en el siguiente ejemplo, usando un desplazamiento de composición "[-geometry](https://imagemagick.org/command-line-options/#geomtry)". Básicamente, estos ejemplos muestran que el operador Layers Composite en realidad entiende los ajustes individuales de desplazamiento del lienzo virtual ("[-page](https://imagemagick.org/command-line-options/#page)") y los manejará, igual que lo harían los operadores Layers Flatten o, mejor aún, Layers Merge. Pero el operador Layers Composite también entiende el uso de un desplazamiento de geometría de composición ("[-geometry](https://imagemagick.org/command-line-options/#geometry)") (cero por defecto), para controlar la colocación global de toda la secuencia de imágenes superpuestas. Incluso entiende los efectos de "[-gravity](https://imagemagick.org/command-line-options/#gravity)" sobre ese desplazamiento global. Por ejemplo... superpongamos nuestra animación original de la 'K' al 'Sur' de la animación de sombra generada... |

  magick shadows_k.gif  null:  coalesced_k.gif  \
          -geometry +0-10 -gravity South  -layers Composite \
          magick composite_south.gif

[IM Output]
Lo anterior también muestra que, igual que en la composición alfa normal de dos imágenes, es la secuencia de imágenes destino la que controla el tamaño final de la imagen de salida, y cualquier superposición de composición se recortará al lienzo de la imagen destino. Por ello, debe asegurarse de que todas las imágenes destino sean lo bastante grandes para contener los resultados finales. | La capacidad de redimensionado de "[-geometry](https://imagemagick.org/command-line-options/#geometry)" no forma parte estrictamente de la operación de composición; solo redimensiona la última imagen de la secuencia de imágenes actual. Por ello, no hará lo que espera si se usa con una composición de capas de varias imágenes. Vea Geometría de redimensionado para detalles.
---|---
Básicamente, la composición de capas es muy parecida a la composición normal.
Bastante sencillo, en realidad. ¿Dije sencillo?
Detalles de la composición de capas......Como vio arriba, la versión de línea de comandos de "[-layers](https://imagemagick.org/command-line-options/#layers) Composite" usa la primera imagen '[null:](files.html#null)' encontrada en la lista de imágenes actual como marcador para separar las dos listas. Las dos listas de imágenes se separan y el 'null:' se descarta antes de que las dos listas se compongan en alfa juntas, de dos en dos imágenes. Solo una imagen generada a partir de la fuente de imagen especial '[null:](files.html#null)' puede usarse como marcador, y si no se encuentra, se informará de un error. Actualmente no puede leer esta imagen marcadora '[null:](files.html#null)' desde una tubería (al menos no por ahora), solo generarla cuando se necesite. La composición de capas también es bastante más compleja que una simple composición alfa de dos imágenes, ya que también se tiene en cuenta el lienzo virtual de las imágenes de la lista. Normalmente, la composición alfa ignora cualquier tamaño y desplazamiento del lienzo virtual a efectos de posicionamiento, usando solo el tamaño real de las imágenes. Este método especial de capas usa la información del lienzo virtual, para el posicionamiento por geometría, de modo que se alineen las dos secuencias de imágenes. Con este fin, cualquier desplazamiento del lienzo virtual que tenga un subfotograma también se añade al desplazamiento de composición "[-geometry](https://imagemagick.org/command-line-options/#geometry)" ajustado por la habitual "[-gravity](https://imagemagick.org/command-line-options/#gravity)", para calcular la posición de la superposición de la imagen. Solo se usa el tamaño del lienzo virtual "[-page](https://imagemagick.org/command-line-options/#page)" de la primera imagen de cada lista para calcular el ajuste de "[-gravity](https://imagemagick.org/command-line-options/#gravity)" al desplazamiento de composición "[-geometry](https://imagemagick.org/command-line-options/#geometry)". El tamaño del lienzo de las imágenes posteriores se ignora, y solo se añade el desplazamiento individual del lienzo virtual "[-page](https://imagemagick.org/command-line-options/#page)" al desplazamiento "[-geometry](https://imagemagick.org/command-line-options/#geometry)" calculado. En otras palabras, "[-layers](https://imagemagick.org/command-line-options/#layers) Composite" está diseñado para la composición alfa de «capas» o «animaciones», y los requisitos especiales de tales listas de imágenes. Advertencias...Aun así, debe tener cuidado con las listas de imágenes que está superponiendo. Si, por ejemplo, las imágenes de la lista destino no son lo bastante grandes, o están posicionadas incorrectamente para contener la imagen fuente superpuesta, la imagen superpuesta se recortará, o no alcanzará la imagen destino en absoluto. Por esta razón, es buena idea combinar (coalesce) las imágenes destino al tamaño completo del lienzo, antes de superponer imágenes fuente más pequeñas. Por ejemplo, vea los ejemplos de concatenación de animaciones lado a lado más abajo, donde el tamaño del lienzo necesitaba expandirse para dar espacio a las imágenes concatenadas. Además, si la lista de imágenes fuente es una animación GIF, puede que necesite asegurarse de que los subfotogramas estén limpios de cosas como: optimizaciones de compresión, y optimizaciones de fotogramas sofisticadas; o podría tener problemas. Por otro lado, una animación de fotogramas borrados o una animación combinada (coalesced) puede componerse directamente con '[Composite](#composite)' sin ningún problema. Solo recuerde que la composición de capas no entiende ningún método de descarte GIF existente que pueda estar presente en las imágenes, aunque preserva los metadatos GIF de la animación destino, tales como: método de descarte, retardo de fotograma y límites de iteración del bucle. La única excepción a esto se da en un caso especial más abajo.

Composición con una sola imagen - componer imágenes con una sola imagen

Normalmente, dos listas de imágenes de igual longitud se componen juntas, un par de imágenes a la vez, hasta que cualquiera de las dos listas de imágenes se agote. Ninguna de las listas de imágenes se repetirá. La composición simplemente se detendrá. Le queda solo la lista de imágenes destino original con las composiciones añadidas. La imagen separadora '[null:](files.html#null)' y todas las imágenes fuente se eliminan de la lista de imágenes actual. Una interfaz de API para este método de capas debería permitirle producir dos listas de imágenes separadas, y quedará a su cargo eliminar ambas listas de imágenes de entrada que se usaron para generar la lista de imágenes resultante. El separador '[null:](files.html#null)' no debería ser necesario.
Sin embargo, si una de las listas solo contiene una sola imagen, esa imagen se compondrá contra todas las imágenes de la otra lista. No importa si esa sola imagen es una imagen fuente o una imagen destino. El método hará la composición contra la otra lista de imágenes, y preservará los metadatos GIF de la lista de imágenes, en lugar de los de la sola imagen, incluso si esa imagen es la imagen destino. Esta «composición contra una sola imagen» es un caso especial de la composición de capas, y es muy útil para añadir un fondo a una animación (vea a continuación), o para insertar un objeto estático en una animación.

Fondo estático - componer sobre un fondo más grande

Por ejemplo, usando este método especial de composición de capas con una sola imagen podemos componer una animación sobre un fondo estático... |

  magick -size 100x100 plasma:fractal null: \( script_k.gif -coalesce \) \
              -gravity Center   -layers Composite \
          -layers Optimize   magick composite_background.gif

[IM Output]
Como la imagen de fondo es la destino, define el tamaño final de la animación, pero todos los metadatos (retardos, etiquetas, comentarios, etc.) provendrán de la lista de imágenes fuente. Normalmente esa información proviene de la lista de imágenes destino. Esta es la única vez que la imagen fuente proporciona los metadatos durante una composición de imágenes. Note también que, como la composición de capas entiende "[-gravity](https://imagemagick.org/command-line-options/#gravity)", la imagen queda correctamente centrada, sin que usted necesite hacer los cálculos por sí mismo. Sin embargo, si los fotogramas fuente contenían desplazamientos, estos también se añadirán a la posición definida por la gravedad, de modo que la posición relativa de todos los subfotogramas siga siendo correcta. Note que, como la animación "[script_k.gif](../static/img/images/script_k.gif)" es en realidad un tipo de animación de superposición, existen métodos alternativos de añadir un fondo estático a la animación. Vea la sección anterior sobre eliminar la transparencia para un ejemplo (sobre un color sólido, pero puede ser cualquier imagen). Lo mismo vale para la aún más sencilla animación de fotogramas borrados. En ese caso, ni siquiera necesita combinar (coalesce) la animación primero, sino que puede componerla directamente sobre una imagen de fondo. Sin embargo, puede que necesite "[-set](https://imagemagick.org/command-line-options/#set)" el método 'dispose' que se usa después, o mejor aún optimizar la animación totalmente combinada (coalesced). No obstante, cualquier otro tipo de animación optimizada requerirá esa operación "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)", y una composición completa con todos los fotogramas de la animación. Por ello, probablemente sea mejor usar el método anterior, solo para asegurarse de que todas las animaciones GIF se manejen correctamente.


Todo lo que reluce...

Animaciones de purpurina

Los métodos de composición de capas anteriores facilitan mucho la generación de animaciones sencillas, como la purpurina. Primero necesitamos algo de purpurina que sea lo bastante grande para cubrir la imagen que se está procesando. Aquí generaré una animación de purpurina de tres imágenes a partir de algunas imágenes de motas aleatorias. Primero, esto es una purpurina cruda en blanco y negro sobre transparencia pura, generando 3 fotogramas de purpurina separando los tres canales de color en imágenes de canal en blanco y negro. Es básicamente un punto de partida crudo para generar cualquier otro tipo de purpurina. El umbral del '30%' controla cuántos «puntos» hay por fotograma. |

  magick -size 100x100 xc: +noise Random -separate \
          null: \( xc: +noise Random -separate -threshold 30% -negate \) \
              -compose CopyOpacity -layers composite \
          -set dispose background -set delay 20 -loop 0   glitter_overlay.gif

[IM Output]
A partir de esta purpurina «cruda» puede superponerla usando una composición alfa '[Screen](compose.html#screen)' para solo aclarar algo de color, generando una purpurina de un color específico. Uso el método Border Flatten (arriba). Solo un color liso... |

  magick glitter_overlay.gif \
          -compose Screen -bordercolor GoldenRod -border 0x0  glitter_gold.gif

[IM Output]
Usando la composición de capas, también puede usar una sola imagen, o incluso varias imágenes, para proporcionar un fondo de color variable. Por ejemplo, aquí genero tres imágenes de plasma fractal, para dar una coloración ligeramente aleatoria al patrón de purpurina. |

  magick glitter_overlay.gif null: -size 100x100 \
          plasma:red-firebrick plasma:red-firebrick  plasma:red-firebrick \
          -compose Screen -layers composite    glitter_plasma.gif

[IM Output]
Por supuesto, hay muchos otros estilos de purpurina y patrones de movimiento. Puede encontrar y descargar muchos de esos mosaicos de purpurina en la WWW. Para aplicar una purpurina como esta a una imagen, hay varios métodos diferentes. Normalmente se enmascara la purpurina a una forma o un fondo específicos. Para esto puede usar una forma transparente (compuesta usando DstIn)

  magick -size 100x100 -fill white -background none -font Candice \
          -gravity center -pointsize 90 label:A   glitter_mask_trans.gif
  magick glitter_plasma.gif null: glitter_mask_trans.gif -alpha set \
          -compose DstIn -layers composite        glitter_masked_trans.gif

[IM Output] [IM Output]

O una imagen de máscara en blanco y negro (compuesta usando CopyOpacity)

  magick -size 100x100 -fill white -background black -font Candice \
          -gravity center -pointsize 90 label:A    glitter_mask.gif
  magick glitter_plasma.gif null: glitter_mask.gif -alpha off \
          -compose CopyOpacity -layers composite   glitter_masked.gif

[IM Output] [IM Output]

Bien, tenemos un área que ha sido enmascarada; puede completar la imagen, generalmente superponiendo la purpurina enmascarada sobre la imagen original. Sin embargo, en nuestro caso colocaré debajo un fondo, y superpondré un borde. |

  magick glitter_masked.gif -size 100x100 \
          null: gradient:gold1-gold4 -compose DstOver -layers composite \
          null: \( -fill none -background none -stroke white -strokewidth 2 \
                   -font Candice -gravity center -pointsize 90 label:A \) \
              -compose over -layers composite      glittered_letter.gif

[IM Output]
Este último ejemplo también limpió cualquier problema de transparencia GIF mediante la eliminación de toda la transparencia de la imagen final y la superposición de un borde suave alrededor de la región con purpurina. | Aunque en lo anterior puede que haya usado imágenes en formato GIF para poder mostrar con magick los pasos individuales del proceso, en la práctica usted combinaría todos los pasos en un solo comando, o usaría un mejor formato de archivo de imagen intermedio como MIFF. Es decir, se hace para evitar los problemas inherentes del formato GIF, hasta que hayamos terminado.
---|---

Mosaicos de purpurina - colocar debajo con «agujeros en la imagen»

Como se mencionó, hay muchas imágenes de mosaicos de purpurina animados ya preparadas disponibles en la WWW (haga una búsqueda de "glitter tiles"). Una fuente es un usuario de IM Studio, scri8e, y su sitio web Moons Stars. Sin embargo, esté advertido de que encuentro que la mayoría de los mosaicos de purpurina se ven bastante horribles, o son demasiado rápidos. Para este ejemplo encontré y modifiqué un mosaico de purpurina azul con algunos pequeños patrones de estrellas. Pensé que sería útil para darle al mago de IM una vestimenta reluciente, haciéndolo parecer realmente mágico. Probablemente la manera más fácil de dar purpurina a una imagen existente es recortar agujeros en la imagen en lugar de intentar enmascarar el patrón de purpurina. Sin embargo, esto solo funciona para imágenes que no contienen transparencia de entrada. Como alternativa, podría eliminar la transparencia de una imagen y, al terminar, volver a añadir la transparencia original. Así que tomemos el logo de IM Examples, y usemos el reemplazo de color para recortar todas las partes azules de la imagen. Algo así como dar a nuestro mago un manto de invisibilidad ;-)

  magick logo.gif -alpha set -fuzz 33% -transparent blue logo_holed.gif

[IM Output] [IM Output]

Note el uso del factor de difuminado (Fuzz) para ajustar cuánto del color azul debe eliminarse. Sin embargo, esté advertido de que esta no es una buena manera de recortar un área de una imagen, ya que produce bordes con aliasing. Pero por ahora no hay disponible ninguna función sencilla de recorte con difuminado de bordes. De acuerdo, tenemos una imagen con un agujero (o muchos agujeros). El siguiente paso es colocar debajo la imagen del mosaico de purpurina. El problema es que el mosaico anterior es demasiado pequeño, ¡no cubrirá toda la imagen! Lo siguiente usa una técnica ingeniosa para repetir en mosaico el mosaico de purpurina de varias imágenes. No obstante, todavía necesita dar un tamaño que sea mayor que la imagen original para asegurarse de que pueda cubrirla por completo. |

  magick glitter_blue.gif -virtual-pixel tile \
          -set option:distort:viewport 180x180 -distort SRT 0 \
          glitter_blue_tiled.gif

[IM Output]
Ahora vistamos a nuestro mago con sus nuevas ropas, colocando la purpurina en mosaico anterior bajo la imagen «con agujeros». |

  magick logo_holed.gif null: glitter_blue_tiled.gif \
          -compose DstOver -layers composite \
          -loop 0 -layers Optimize logo_glittered.gif

[IM Output]
Por supuesto, puede hacer todos estos pasos en un solo comando. Aquí limito la generación de agujeros solo al manto del mago, que tiene dos partes específicas separadas. |

  magick logo.gif -alpha set -fuzz 10% -fill none \
          -draw 'matte 120,150 floodfill  matte 150,120 floodfill' \
          null: \( glitter_blue.gif -virtual-pixel tile \
            -set option:distort:viewport 300x300 -distort SRT 0 \) \
          -compose DstOver -layers composite \
          -loop 0 -layers Optimize logo_glitter_cloak.gif

[IM Output]
Los agujeros anteriores se crearon usando primitivas de dibujo Matte Fill para seleccionar un punto y color reales de la imagen para el reemplazo de color. Esto significa que no necesito usar un factor de difuminado (Fuzz) tan alto como el que usé originalmente, ya que mi color de comparación provino de las áreas específicas seleccionadas. Además, usé un «viewport» de mosaico más grande para asegurarme de cubrir por completo la imagen que se repite en mosaico, sin necesidad de conocer sus dimensiones exactas. | _El uso del operador de distorsión general y su opción especial 'viewport' (añadida en IM 6.3.6-0), también le da la oportunidad de modificar el patrón de distorsión de otras maneras especiales. Como darle un aspecto de «perspectiva» o rotar el patrón a ángulos no rectangulares. Hacer esto puede mejorar el mosaico de modo que no tenga un aspecto tan uniforme.

Para ver algún ejemplo, vea Mosaico afín._
---|---

Destellos - superponer purpurina mayormente transparente

El gran problema con las dos técnicas anteriores de animación de purpurina es que son un tipo de reemplazo de todo o nada. No puede usar el sombreado o el fondo originales de la imagen. Además, la purpurina queda completamente restringida al área que fue enmascarada. No puede extenderse más allá de los límites del área implicada. Por ello, algunas áreas pequeñas, como el «sombrero» del mago en el ejemplo anterior, no manejan muy bien la purpurina. Los destellos son diferentes, en que la animación añadida es mayormente transparente. Como consecuencia, la imagen original todavía puede transparentarse. Tales animaciones suelen añadirse a una imagen de una de dos maneras. O bien la propia superposición de animación es transparente, o tiene la forma de un fondo negro con «chispas» blancas donde la imagen debe aclararse.

En construcción

Aquí hay un ejemplo de una superposición de «destellos» mayormente transparente. Ejemplo aquí Como puede ver, puede tener superposiciones de destellos coloridas cuando se usa esta forma. El gran problema con esto es que se usó una animación GIF para guardarla (lo cual suele ser el caso), así que la superposición tiene un fuerte aliasing. Es decir, no puede contener ningún píxel semitransparente para suavizar el aspecto de la imagen superpuesta. Si lo hiciera, obtendría horribles halos negros alrededor de los «destellos» en el resultado final. Enmascaremos esto y superpongámoslo sobre el mago. Ejemplo aquí La otra forma de destellos es destellos blancos sobre un fondo negro (una imagen en escala de grises). Estos se enmascaran y superponen de modo que aclaran la imagen para añadir el destello. Por ejemplo... Ejemplo aquí Una de las mejores cosas de los destellos es que puede generar una secuencia de fotogramas en la que los destellos aparecen lentamente y luego desaparecen. Esto puede volverse bastante complejo, pero no es muy difícil de hacer. Ejemplo aquí

Añadir animaciones de fulgores y estrellas

Mientras que la purpurina consiste en puntos individuales de brillo, y los destellos pueden superponerse a algunas áreas de una imagen, los fulgores normalmente se añaden de forma individual. Un «fulgor» es básicamente un punto que destella para cubrir un área grande durante solo un momento. Una «estrella» es similar, salvo que la cobertura tiene más bien la forma de «rayos» de brillo. Estos normalmente se «siembran» desde puntos específicos, pero el resultado a menudo se extiende, al menos momentáneamente, bastante más allá del área de siembra. Por ejemplo, un fulgor que está limitado por una máscara a un área específica se ve muy, muy estúpido y antinatural. Los aspectos más difíciles de los fulgores son localizar buenos puntos de «siembra» y temporizar varios fulgores apropiadamente.

En construcción

Ejemplo final que quiero crear...  Un 'destello' que sube por la varita del
mago, luego estalla, y se disuelve en una serie de pequeños fulgores de destello sobre
un área.  Luego la secuencia se repite.

Redimensionar animaciones

Problemas al redimensionar animaciones

El mayor problema al redimensionar animaciones GIF es que el operador "[-resize](https://imagemagick.org/command-line-options/#resize)" está diseñado específicamente para hacer que las imágenes resultantes sean lo más cercanas posible a lo ideal (tras el redimensionado). Lo hace fusionando y generando muchos colores adicionales en la imagen para que se vea mejor. Las imágenes resultantes están lejos de ser ideales para guardar en el limitado formato de archivo GIF. Con la limitada tabla de colores del GIF, esto resulta en fuertes reducciones de color en las imágenes redimensionadas. Para una sola imagen GIF eso no es tan malo, pero para animaciones GIF, el tramado por corrección de error por defecto del conjunto de colores reducido produce problemas, en forma de «ruido de tramado» entre fotogramas, y a su vez una mala optimización de fotogramas para el tamaño final del archivo. Es aún peor cuando también se usan colores transparentes, lo cual es una práctica común en las típicas animaciones GIF usadas para páginas web. La transparencia también se usa comúnmente para técnicas de optimización de compresión, en animaciones que de otro modo no la necesitarían. Lo que sucede es que "[-resize](https://imagemagick.org/command-line-options/#resize)" produce píxeles semitransparentes en las imágenes de superposición. Luego, cuando las imágenes se guardan de vuelta en un formato de archivo GIF, esos píxeles se convierten en totalmente transparentes o totalmente opacos, lo que produce grandes distorsiones de color en la animación resultante. Si se usa cualquier forma de optimización... de fotogramas, transparencia o LZW... entonces los efectos de la transparencia básicamente resultarán en una animación GIF redimensionada de forma desastrosa. Esos son los hechos, ¡colega! Así que tendrá que vivir con ello. Incluso si evita usar "[-resize](https://imagemagick.org/command-line-options/#resize)", usando "[-sample](https://imagemagick.org/command-line-options/#sample)", todavía tendrá grandes problemas a menos que primero "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)" la animación.

Técnicas para redimensionar animaciones

Como se mostró arriba, hay serios problemas al redimensionar animaciones GIF, ninguno de los cuales se resuelve fácilmente. La solución también depende generalmente de qué tipo de imagen se redimensionó en primer lugar, sea de tipo caricatura, o una imagen de vídeo del mundo real. Aquí están los métodos que conozco, o que han sido aportados...

Evitar el redimensionado

Si es del todo posible, NO REDIMENSIONE. Por ejemplo, puede aplicar un recorte de lienzo o por viewport a su animación para recortarla y que encaje en el espacio que necesita. O puede generar la animación GIF al tamaño correcto desde el principio. Ninguna de las dos técnicas suele ser la mejor opción, pero si puede, considérela, ya que le ahorrará muchos problemas y dolores de cabeza.

Redimensionado directo

Como se mencionó, usar "[-resize](https://imagemagick.org/command-line-options/#resize)" directamente tendrá problemas, ya sea con el número de colores de cada fotograma, o con los colores semitransparentes. Por ejemplo, esto sale realmente mal... |

  magick script_k.gif -resize 20x20 script_k_direct.gif

[IM Output]
[IM Output]
Bueno, eso no funcionó muy bien, y eso se debe a que la imagen original tiene algunas fuertes optimizaciones de fotogramas. Cada «fotograma» de la animación no tiene el mismo tamaño, y "[-resize](https://imagemagick.org/command-line-options/#resize)" redimensionará todos y cada uno de los fotogramas de forma completamente separada de las demás imágenes. Es decir, lo anterior redimensionó las imágenes de fotograma reales, y no el lienzo virtual de la animación, al tamaño dado. En realidad me sorprende que la animación resultante no fuera más «loca» que la simple área en blanco mostrada. Eso nos lleva al primer punto sobre el redimensionado de animaciones. Primero asegúrese de que todos los fotogramas estén totalmente definidos, y de que se haya eliminado TODA optimización. En otras palabras, combine (coalesce) la animación antes de intentar redimensionarla. Por ejemplo... |

  magick script_k.gif -coalesce  -resize 20x20  script_k_direct2.gif

[IM Output]
[IM Output]
El siguiente problema es el de los colores de transparencia. Si observa el resultado anterior, verá que los bordes de la animación más pequeña tienen un horrible aliasing (efecto «escalera»). Eso se debe a que GIF no puede guardar los colores semitransparentes que generó el operador "[-resize](https://imagemagick.org/command-line-options/#resize)". Los colores dentro del objeto animado también se habrán fusionado para producir nuevos colores, pero eso normalmente no es ni de cerca tan malo como el aliasing de los bordes.

Redimensionar con aplanado: una solución general.

La mejor idea al generar una miniatura GIF es evitar por completo los problemas de la transparencia. Es decir, aplane la animación, ya sea antes o después de redimensionarla. De esa manera no pierde el «antialiasing» de los bordes en las imágenes redimensionadas. De hecho, he comprobado que la mayoría de los buenos sitios web de animaciones GIF hacen exactamente eso al generar sus miniaturas de animaciones GIF. Por supuesto, la miniatura quedará entonces limitada a usarse sobre un fondo de un color específico, normalmente «blanco», pero a veces «negro», o «plata» (el gris de las páginas web), aunque este último es menos común hoy en día. Por ejemplo, aquí creo una miniatura más pequeña sobre un color de fondo apropiado para esta página web. |

  magick script_k.gif -coalesce \
          -bordercolor LightSteelBlue -border 0 \
          -resize 20x20  -layers Optimize   script_k_thumbnail.gif

[IM Output]
[IM Output]
Esta es la solución recomendada para el manejo general de miniaturas GIF. Cualquier otro método requiere o bien control humano, o una lógica de manejo de miniaturas GIF muy sofisticada.

Desbordamiento de la tabla de colores

El mayor problema (como mencioné al inicio de esta sección) es que se genera un enorme número de colores adicionales en la imagen, especialmente cerca de las líneas y los bordes de las áreas de color adyacentes. También obtiene un halo de redimensionado de colores semitransparentes alrededor de los bordes de las imágenes. Esto, a su vez, agranda el tamaño de la tabla de colores necesaria para una animación de colores mínimos sencilla, lo que a su vez significa un tamaño de archivo mayor cuando se guarda una animación sencilla redimensionada. Peor aún, todos y cada uno de los fotogramas de la animación redimensionada probablemente generan un conjunto de colores diferente, lo que agranda aún más el tamaño del archivo de su animación «en miniatura». También está el problema de que, tras la cuantización de color, puede que ya no tenga los mismos colores específicos que la animación original (vea La cuantización NO preserva los colores). Es decir, en lugar de tener un área de blanco puro, ahora puede tener un área de blanco apagado.

Redimensionar usando Sample

Para evitar generar colores adicionales al redimensionar, la manera más simple es usar "[-sample](https://imagemagick.org/command-line-options/#sample)" sobre la animación, en lugar de redimensionarla. Esto preservará los colores actuales de la animación y le permitirá volver a optimizar fácilmente la animación al nuevo tamaño. |

  magick script_k.gif -coalesce  -sample 20x20  script_k_sample.gif

[IM Output]
[IM Output]
Sin embargo, aunque esto funciona, básicamente está eliminando filas y columnas de píxeles de la imagen, perdiendo datos de imagen y, por tanto, calidad en el proceso. Con imágenes de tipo caricatura, eso a menudo deja bordes «punteados» y detalles faltantes o distorsionados. Si su redimensionado es de más del 50% del tamaño original de la animación, como ocurre arriba, el resultado suele ser bastante horrible, especialmente cuando se usa textura u otro patrón de color en la animación. No es de extrañar entonces que muchas bibliotecas de animaciones GIF estén llenas de esas horribles animaciones redimensionadas con sample que han copiado de toda la red. A menudo desearía que limpiaran este tipo de basura, pero eso significa reducir el número de GIF en oferta, y eso a su vez reduce las estadísticas de marketing del número de GIF disponibles, lo cual no le gusta al departamento de publicidad. Como consecuencia, las animaciones GIF malas son comunes.

Redimensionar usando Liquid Resize

Un método similar al de usar Sample anterior es usar Liquid Rescale, también conocido como Seam Carving. Este también elimina o añade píxeles enteros de las imágenes implicadas, pero intenta hacerlo de manera que se preserve la mayor cantidad posible de la complejidad de la imagen. Mire los enlaces anteriores para ver cómo puede usarlo para generar imágenes redimensionadas más agradables. Por desgracia, por ahora no hay manera de usar esto en una imagen animada general, ya que no tiene una comprensión de la complejidad de una imagen, y actualmente no podemos extraer el método de reescalado para aplicarlo a cada fotograma de una animación de forma consistente. Con suerte esto cambiará en algún momento del futuro.

Redimensionar y restaurar colores

Aplicar sample a una animación solo resulta en eliminar filas y columnas de píxeles, y la posible eliminación de líneas finas y otros detalles importantes. Pero fusionar píxeles usando "[-resize](https://imagemagick.org/command-line-options/#resize)" produce demasiados colores nuevos para el formato GIF. Así que la solución obvia es hacer el "[-resize](https://imagemagick.org/command-line-options/#resize)" pero luego usar los colores de la animación original para restaurar los colores de la animación redimensionada, usando un mapa de colores.

FUTURO: ejemplo con la tabla de colores original restaurada

Esto tiene la ventaja añadida de no generar tablas de colores locales. Sin embargo, los resultados pueden ser mejores con el tramado desactivado, para evitar cualquier «ruido de tramado». Esto es especialmente cierto para imágenes de tipo caricatura que tienen grandes áreas de color liso.

FUTURO: ejemplo con tabla de colores restaurada sin tramado

Optimización de color completa

Si una horrible miniatura con sample no es de su agrado, entonces se enfrenta a la perspectiva de pasar por una optimización de color completa de la animación GIF redimensionada. Para decidir qué colores «nuevos» quiere que la animación conserve. Sin embargo, esto a menudo no es tan malo, para la mayoría de las animaciones, pero puede ser un gran esfuerzo para animaciones más complejas, como cuando se convierte un vídeo a animación GIF. Es decir, si está tratando con una animación de tipo caricatura, ahora tendrá líneas y bordes con fuerte antialiasing. Para animaciones que involucran un fondo transparente, también tendrá que tratar correctamente los píxeles semitransparentes alrededor del borde de su animación, también causados por las características de antialiasing del redimensionado. Vea la sección sobre transparencia booleana del GIF para los muchos métodos que puede usar para manejar esto.

Reducciones de redimensionado grandes

Cuando planea redimensionar una animación grande a una animación mucho más pequeña, se enfrenta al problema de que partes importantes de la animación desaparezcan. Esto es en realidad un problema tanto para las imágenes estáticas como para las animaciones. Vea Redimensionar dibujos lineales para conocer las soluciones conocidas para esto.
Cualquier otra sugerencia, idea o técnica es muy bienvenida.


Fusionar varias animaciones

Lo dije antes, pero se vuelve especialmente importante al fusionar animaciones...

¡Conozca todo lo que pueda sobre la animación con la que está trabajando!

El script "[gif2anim](../static/img/scripts/gif2anim)" es ideal para este propósito. Su script hermano "[anim2gif](../static/img/scripts/anim2gif)" también se usa comúnmente aquí para recrear una animación usando sus ajustes originales. (Vea el uso básico del script en Información de la lista de animación.) Sin conocimiento de cómo funciona una animación es casi imposible fusionarlas de diversas maneras. Se pueden desarrollar programas (el objetivo último de estos ejemplos) para hacer esto. Pero tales programas a menudo son muy complejos y pueden producir resultados inesperados. Debido a esto, aun así debe seguir estos ejemplos, ya que le darán una gran perspectiva de cómo deben manejarse y fusionarse las animaciones.

Concatenación en serie o temporal

Concatenar dos animaciones GIF de modo que una secuencia siga a otra en el tiempo es sencillo con IM. Básicamente solo las lista en la línea de comandos y se seguirán una a otra. Pero puede no ser tan fácil como parece. Por ejemplo, tras buscar algo en la web, encontré (bueno, robé y modifiqué mucho para este ejemplo) un par de animaciones de unas letras que se dibujan. Ahora me gustaría unir estas imágenes para que cuando una animación termine empiece la siguiente, como si alguien estuviera escribiendo la palabra 'OK'. Aquí están las letras, la «secuencia de animación» y los detalles de las interioridades de estas dos animaciones. | |

  gif2anim -n script_o.gif
  gif2anim -n script_k.gif

| [IM Text]

| | [IM Text]

[IM Output]
[IM Output]
Estas secuencias empiezan con un lienzo vacío y luego, lentamente, solo añaden y modifican píxeles en este lienzo. Nunca eliminan, borran ni hacen transparente ningún píxel añadido por fotogramas previos. Para nuestros propósitos, sin embargo, no importa si lo hacen o no, ya que tendrá poca relevancia en los resultados. Tampoco el número de fotogramas de la animación tendrá relevancia en esta operación. Lo importante que hay que saber son las temporizaciones del fotograma, ya que esto podría producir problemas. En particular, note el retardo de tiempo del primer fotograma, o en este caso, del último fotograma. Esta técnica es muy común, dándole al espectador tiempo de ver el resultado final antes de que la animación se borre y se reinicie. Son estos retardos y fotogramas los que nos causarán problemas al hacer concatenaciones temporales. Note también que la animación 'k' tiene un ligero retardo en mitad de la secuencia de animación. Este retardo representa el final del primer trazo de pincel de esta animación y el segundo trazo de pincel. Este retardo también necesitará preservarse, lo que significa que no podemos simplemente cambiar todas las secuencias de tiempo de la animación a un valor constante. Algo que no se muestra en lo anterior es que el primer fotograma de ambas animaciones es en realidad un lienzo en blanco. Probablemente querremos descartar ese lienzo en la segunda animación como una pérdida de tiempo inútil, aunque debería conservarse en la primera animación como un retardo inicial. Ahora que hemos examinado las dos animaciones, intentemos unirlas para que una siga a la otra en el tiempo. Concatenar animaciones en el tiempo es en realidad una operación muy simple, solo concatene las dos imágenes animadas en la línea de comandos. Así que probemos eso... |

    magick script_o.gif script_k.gif   script_ok_try1.gif

[IM Output]
Pues bien, el resultado distó mucho de ser perfecto. Las letras se dibujan en la secuencia correcta, ¡pero una encima de la otra! No solo eso, sino que como la primera animación de la 'o' es más estrecha (40 píxeles) que la segunda animación de la 'k' (53 píxeles), el último trozo de la letra 'k' final queda recortado por ese tamaño de lienzo de encuadre más pequeño. La posición de la segunda animación se puede mover usando un repage relativo, como se mostró arriba. Este método de reposicionamiento preservará cualquier desplazamiento existente que pueda estar presente en esa animación, simplemente moviéndolos todos como un único grupo relacionado. En este caso, casi todos los fotogramas tienen un desplazamiento existente, ya que esta es una animación muy optimizada. Para acomodar esta posición desplazada y evitar el «recorte» de la segunda animación, también necesitamos agrandar el tamaño del lienzo de toda la animación. Cambiar el tamaño del lienzo antes de leer la primera animación o fotograma agrandará el área de lienzo en la que corre la animación, y evitará que la 'K' quede recortada. |

    magick -page 90x54 script_o.gif \
            \( script_k.gif -repage +37+0\! \)   script_ok_try2.gif

[IM Output]
El resultado es una gran mejora. Aunque ahora los retardos entre el dibujo de las letras son claramente perceptibles. Lo que queremos es un retardo mucho más pequeño para el último fotograma de la primera animación de la 'O'. Justo lo bastante grande para que parezca que el artista invisible está reposicionando el bolígrafo. Para hacer esto, hacemos una copia de ese último fotograma de la primera animación, y luego cambiamos el retardo solo de ese fotograma usando el operador "[-set](https://imagemagick.org/command-line-options/#set)". Luego volvemos a añadir ese fotograma a la secuencia de imágenes eliminando la imagen original sin modificar. Además, como ahora hemos establecido un buen retardo entre el dibujo de las letras, el lienzo en blanco inicial (que solo representa un retardo de inicio inicial) de la segunda animación es ahora redundante, así que podemos simplemente eliminar ese fotograma, sin problemas. Si este fotograma realmente contuviera parte de la imagen, entonces puede que necesitemos ajustar su retardo, en lugar de eliminarlo. |

    magick -page 90x54 script_o.gif \( +clone -set delay 20 \) -delete -2 \
            \( script_k.gif -delete 0 -repage +37+0\! \)     script_ok.gif

[IM Output]
Y nuestra concatenación en serie o temporal de dos animaciones está completa, y todos los pequeños problemas asociados con estas dos animaciones particulares están resueltos. Note que en ningún momento intenté cambiar globalmente TODOS los fotogramas individuales, ni sus retardos de temporización. Es decir, preservé tanto de las animaciones originales como pude, mientras lograba mi objetivo. Esto es importante, ya que no todas las animaciones usan un retardo de temporización constante entre fotogramas, y cambiar esto puede hacer que una animación se vea muy mal.

Concatenación lado a lado (sincronizada en el tiempo)

Suponga que quiere concatenar ambas animaciones lado a lado, pero que ambas partes de la animación se animen al mismo tiempo. Esto no es tan fácil, ya que necesita concatenar (o componer juntos) cada par de fotogramas de las dos animaciones, de modo que la animación también funcione en conjunto. El verdadero problema para hacer esto es que la línea de comandos de IM solo trabaja con una única secuencia de imágenes. No tiene el lujo de una API donde pueda mantener dos secuencias de imágenes separadas, para recorrerlas y concatenarlas en una tercera. Puedo pensar en tres técnicas básicas para hacer esta concatenación. Antes de empezar, sin embargo, primero debe estudiar las dos animaciones, para comprobar las secuencias de tiempo y otros detalles de la animación. El script "[gif2anim](../static/img/scripts/gif2anim)" es bueno para esto, y el archivo ".anim" generado puede ser útil más tarde. | |

  gif2anim -n bag_left.gif
  gif2anim -n bag_right.gif

| [IM Text]

| | [IM Text]

[left]
[right]
Si observa los resúmenes de información, verá que las dos animaciones tienen exactamente el mismo número de fotogramas, y casi exactamente la misma secuencia de tiempo. Es la similitud de la temporización lo importante aquí, y puede decir que las animaciones ya están «sincronizadas en el tiempo». Sin embargo, aunque las temporizaciones puedan ser correctas, las animaciones están optimizadas por fotogramas, en lugar de totalmente combinadas (coalesced). Pero la altura del área del lienzo es la misma, lo que hace práctica la concatenación de los dos fotogramas lado a lado. En realidad, esta animación fue mal «dividida» (vea dividir animación en el siguiente conjunto de ejemplos), de modo que la animación del 'gato' quedó cortada en dos, y la original se perdió. Otras modificaciones resultaron en una ligerísima diferencia de temporización, que solo hizo la división más obvia. Este fue un problema que me presentó gmabrys en una discusión en los foros de IM, aunque el problema real que él dio era muchísimo peor. [left][right] Ahora bien, los navegadores normalmente animan cada una de las imágenes GIF separadas, sin ninguna sincronización. Por ello, las dos animaciones pueden desincronizarse entre sí, produciendo un 'gato' que parece haber sido parte de una masacre con motosierra. Puede que sea capaz de ver este efecto a la derecha, donde coloqué dos animaciones lado a lado en la página del navegador, especialmente si está en un servidor distante a través de enlaces lentos. Ahora intentemos concatenarlas juntas en una sola imagen animada, correctamente sincronizada.

Concatenar archivos separados

La manera más simple es simplemente combinar (coalesce) las dos animaciones y separarlas en archivos de imagen separados, un fotograma por imagen. Las imágenes separadas pueden entonces concatenarse (o modificar los fotogramas de otro modo) según corresponda. Cuando esté hecho, los nuevos fotogramas pueden usarse para reconstruir la animación. Esto, sin embargo, requiere que guarde mucha información extra sobre la animación que podría perderse muy fácilmente durante este procesamiento. |

  # Separar las animaciones en fotogramas combinados (más un archivo ".anim")
  gif2anim -c bag_left.gif
  gif2anim -c bag_right.gif

  # Concatenar juntos los fotogramas separados
  for i in `seq -f '%03g' 1 11`; do \
    magick bag_left_$i.gif bag_right_$i.gif +append bag_append_$i.gif; \
  done

  # Reconstruir la animación (usando uno de los archivos ".anim")
  anim2gif -c -b bag_append  bag_left.anim

  # Limpieza
  rm -f bag_left.anim bag_right.anim
  rm -f bag_{left,right,append}_???.gif

[IM Output]
Como puede ver, este es un proceso bastante complicado, que genera muchas imágenes temporales individuales, y por tanto requiere bastante limpieza al terminar. Por supuesto, si está depurando lo anterior, los archivos temporales individuales facilitan averiguar qué está saliendo mal con su procesamiento. También muestra el poder del script "[gif2anim](../static/img/scripts/gif2anim)" y su inverso, el script "[anim2gif](../static/img/scripts/anim2gif)", para separar y guardar los metadatos de la animación, y luego reconstruir más tarde las animaciones GIF. Básicamente le permite preservar las temporizaciones originales de las animaciones, sin necesidad de codificarlas directamente en su script. La imagen final también necesita aún ser re-optimizada, aunque en este caso obtendrá muy poca optimización, ya que muchas cosas están ocurriendo simultáneamente a lo largo de la animación entre todos y cada uno de los fotogramas.

Composición en capas

Una técnica mejor es superponer las animaciones usando una composición de capas de listas de varias imágenes. Esto implica solo agrandar un conjunto de imágenes, y superponer el otro conjunto para unirlas. De hecho, esto es lo que hace internamente el operador "[-append](https://imagemagick.org/command-line-options/#append)" normal, así que no es tan diferente. Aquí solo le digo a IM cómo de grande hacer el lienzo, y lo relleno usando "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)". Luego superpongo la otra animación combinada con un desplazamiento apropiado. |

  magick bag_left.gif -repage 97x92 -coalesce \
          null: \( bag_right.gif -coalesce \) \
          -geometry +50+0 -layers Composite    bag_append.gif

[IM Output]
Por supuesto, la técnica anterior significa que necesitaba saber cómo de grande será la animación final, así como el desplazamiento necesario para la animación superpuesta. Pero el proceso es rápido, funciona muy bien, y un comando con script puede pre-leer las imágenes para determinar esa información. Para hacer un método de concatenación de animaciones más universal, necesitamos hacer algo de manejo de imágenes ingenioso para determinar automáticamente el tamaño y el desplazamiento finales de la concatenación. Para hacer esto sin pre-leer la animación, se requiere pasar por algunos aros, pero es posible una concatenación general de animaciones en un solo comando. Primero necesitamos concatenar el primer fotograma combinado de cada animación para crear un lienzo que sea del tamaño correcto, y luego se borra. La primera animación se combina y se superpone en la mitad izquierda de este lienzo, luego la segunda animación se combina y se superpone con una "-gravity East" para colocarla en la mitad derecha del lienzo preparado de antemano, para evitar la necesidad de un desplazamiento. |

  magick bag_left.gif'[0]' -coalesce \( bag_right.gif'[0]' -coalesce \) \
          +append -channel A -evaluate set 0 +channel \
          bag_left.gif -coalesce -delete 0 \
          null: \( bag_right.gif -coalesce \) \
          -gravity East  -layers Composite    bag.gif

[IM Output]
Y ahí tiene una técnica general para concatenar dos animaciones sincronizadas en el tiempo.

Doble concatenación, concatenar - o concatenar fuentes animadas

Antes de terminar con la concatenación de animaciones, hay otra técnica que me gustaría mostrarle. Esta técnica puede concatenar varias animaciones al mismo tiempo, pero a costa de perder toda la información de temporización que estuviera presente. A menudo (pero no siempre) esas temporizaciones no son una gran pérdida. Básicamente concatenamos todos los fotogramas de cada animación verticalmente en una sola imagen, y luego concatenamos o superponemos toda la animación como dos imágenes sencillas. Esto es algo así como pegar dos tiras de película lado a lado para producir una tira de película más ancha. |

  magick \( bag_left.gif  -coalesce -append \) \
          \( bag_right.gif -coalesce -append \) \
          +append  -crop x92 +repage \
          -set delay 30     bag_dbl_append.gif

[IM Output]
Esto no requirió ningún archivo temporal, pero como mencioné al principio, todos los retardos de tiempo originales se han perdido. Para este ejemplo simplemente establecí todos los retardos de la animación a un valor constante, produciendo un resultado razonable, aunque distinto. Además, para reconstruir la animación necesitábamos conocer la altura de fotograma de la animación original, para dividir correctamente (recorte en mosaico) la «tira de película» ensanchada. Aunque es posible recuperar esas temporizaciones usando los scripts "[gif2anim](../static/img/scripts/gif2anim)", hacerlo derrota en cierto modo el propósito de usar este método, y bien podría haber usado la primera técnica de concatenación de animaciones, concatenando los fotogramas individuales como archivos temporales. Como está concatenando las animaciones como imágenes sencillas, puede concatenar juntas toda una serie de animaciones al mismo tiempo (produciendo una «tira de película» aún más ancha), y eso es lo que hace que esta técnica sea tan útil. Por ejemplo, puede usarla con fuentes animadas que todas usen las mismas temporizaciones. Aunque he comprobado que, si bien muchas fuentes animadas tienen el mismo número de fotogramas, normalmente tienen temporizaciones ligeramente diferentes para cada letra, a fin de desincronizar las letras animadas (vea Dividir una animación para las razones por las que eso es deseable). Un letrero de neón, por otro lado, debería tener temporizaciones de animación sincronizadas, así que lo usaré como ejemplo...

  magick \( neon_h.gif -coalesce -append \) \
          \( neon_e.gif -coalesce -append \) \
          \( neon_l.gif -coalesce -append \) \
          \( neon_l.gif -coalesce -append \) \
          \( neon_o.gif -coalesce -append \) \
          +append  -crop x60 +repage  -set delay 100  neon_hello.gif

[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]

También podría hacer algo un poco más elaborado, ajustando las temporizaciones y el número de bucles de la animación resultante.

  magick neon_h.gif'[0]' neon_e.gif'[0]' neon_l.gif'[0]' neon_l.gif'[0]' \
          +append \( +clone \) -append \
          \( neon_o.gif -coalesce -append \)    +append \
          \( +clone \) -append \( +clone \) -append \( +clone \) -append \
          -crop x60 +repage   -set delay 3 \
          \( -clone 0  -set delay 300 \) -swap 0,-1 +delete \
          \( -clone 1  -set delay  10 \) -swap 1,-1 +delete \
          \( +clone    -set delay 200 \) +swap      +delete \
          -quiet -layers OptimizeFrame   neon_hell.gif

[IM Output]

Las dos primeras líneas crean la parte «siempre encendida» del letrero (el primer fotograma de cada una de las letras previamente animadas). Después de esto se añade la última letra «rota» y toda la animación se duplica un par de veces para producir unos 16 fotogramas. Las temporizaciones se ajustan para completar el efecto deseado, con el primer y el último fotograma mostrándose durante un periodo largo, mientras el resto de los fotogramas pasan volando realmente rápido ( "-delay 10" ). En realidad, esta animación GIF se optimiza a un tamaño mucho menor de lo que probablemente pensaría para el número de fotogramas implicados. Básicamente, el optimizador GIF de IM descubrió que solo necesitaba volver a superponer la animación de la 'O' cada segundo fotograma, y usó un descarte 'Previous' para restaurar simplemente la 'O' encendida previa. Así, la animación es solo un 50% más grande que la imagen 'hello' básica sin optimizar y parpadeante. Compruébelo usted mismo. ¿Puede mejorar la animación de neón? ¿Hacerla más realista? Es una lástima que las animaciones GIF no tengan sonido.

Dividir una animación

Ahora que hemos vuelto a unir la animación, intentemos dividirla correctamente para su uso en servidores web, de modo que las partes individuales puedan animarse por separado, sin interferir entre sí. Esto es en realidad razonablemente difícil, y no intentaré automatizar por completo el proceso. Sin embargo, hay herramientas en la WWW que pueden hacer esto. Primero de todo necesitamos estudiar la animación para encontrar qué partes de la animación cambian a lo largo de todo el periodo. Para eso necesitamos encontrar las diferencias de un fotograma al siguiente, sumarlas todas en un mapa que muestre las áreas que se están animando, frente a las que permanecen completamente estáticas. Esto es delicado. Básicamente, se usa una composición alfa de varias imágenes para encontrar una imagen de '[Difference](compose.html#difference)' entre cada fotograma de la animación. Estas imágenes de diferencia en escala de grises se suman, luego se separan los canales y también se suman. Un umbral final hace que cualquier cambio distinto de cero entre cualquier fotograma de la animación sea blanco puro. El resultado es una imagen negra con blanco en cualquier lugar donde la imagen cambió, resaltando las áreas de cambio.

  magick   bag.gif   -coalesce  -set delay 0 \
          -bordercolor red -border 0 -alpha off    null: \
          -duplicate 1,1--2 -compose difference -layers composite \
          +delete -compose plus -background black -flatten \
          -separate -flatten -threshold 0 bag_areas.gif

[IM Output] [IM Output]

Ahora podemos ver que esta animación podría dividirse en al menos tres áreas: un área de 'gato' en la parte superior, un pequeño 'oso' a la izquierda, y un 'ala' que aletea a la derecha. Todas con cortes ortogonales (verticales u horizontales) simples. Así que hagamos justo esto, con algunos recortes por viewport de la animación sencillos. |

  magick bag.gif -coalesce  -crop 97x39+0+0\!   bag_cat.gif
  magick bag.gif -coalesce  -crop 50x54+0+39\!  bag_bear.gif
  magick bag.gif -coalesce  -crop 47x54+50+39\! bag_wing.gif

| [IM Output]

[IM Output] | [IM Output]
Estas tres imágenes pueden mostrarse juntas por el navegador y no tener el aspecto de la «masacre de Texas con motosierra», ya que en ningún punto una subanimación cruza los límites de otra. Ahora, técnicamente, puede hacer un par de cortes más para separar las áreas que no están animadas de las áreas animadas, dividiendo esta animación en unas seis áreas o más, aunque no ganará mucho con la optimización al hacer esto. Todo lo que realmente haría sería complicar su página web, y crear más archivos para que el usuario descargue. Ahora, a diferencia de la animación más grande, estas áreas más pequeñas se animarán de forma bastante independiente entre sí. Incluso podemos cambiar también las temporizaciones de estas subanimaciones sencillas sin afectar adversamente el resultado, para desincronizarlas por completo de las otras subanimaciones. El resultado es una imagen animada más agradable y menos repetitiva (vea abajo). Si estudia el 'oso saltarín' y el 'ala que aletea', verá que forman un sencillo ciclo de dos fotogramas que simplemente se repite varias veces, para coincidir con la temporización del gato que saluda. Por lo tanto, podemos descartar las repeticiones extra para simplificar estas animaciones. Además, los dos primeros fotogramas del 'gato' también son exactamente iguales. Sin embargo, a diferencia del 'oso' y el 'ala', no puede simplemente eliminar uno de ellos, ya que cada fotograma contiene retardos de tiempo para permitir que el 'oso' y el 'ala' se animen sin que el gato esté presente. Para eliminar correctamente estos fotogramas duplicados, necesita usar el método '[RemoveDups](anim_opt.html#removeDups)' de "[-layer](https://imagemagick.org/command-line-options/#layers)" para localizar y fusionar las temporizaciones de tales fotogramas duplicados en una animación combinada. Y aquí están las optimizaciones finales, de las tres animaciones separadas con los cambios de temporización para mejorar la desincronización general de las subanimaciones. También he mostrado las tres animaciones lado a lado en la página, justo como deberían mostrarse. |

  magick bag_cat.gif -layers RemoveDups \
                           -quiet  -layers Optimize  bag_cat_opt.gif
  magick bag_bear.gif -delete 2--1 -set delay 47 \
                                   -layers Optimize  bag_bear_opt.gif
  magick bag_wing.gif -delete 2--1 -set delay 33 \
                                   -layers Optimize  bag_wing_opt.gif

| [IM Output]

[IM Output] | [IM Output]
Como resumen final: las dos imágenes originales (mal divididas) sumaban [IM Text] bytes, lo cual es aproximadamente lo mismo que la versión concatenada. Tras dividir correctamente la animación, lo que permite una buena optimización de las subanimaciones, obtenemos un total de [IM Text] bytes en tres imágenes. Un ahorro bastante bueno.

Dividir fotogramas con cambios distantes

En construcción

Ejemplo de dividir las actualizaciones de fotogramas de 'dos objetos que cambian y que están muy alejados', sin involucrar transparencia (fondo fijo), pero preservando la sincronización de temporización entre las partes. Luego repetir con un fondo de transparencia (necesitando 'OptimizePlus' para generar los píxeles «borrados»). Vea Dividir acciones de fotogramas para el ejemplo general.

Fusionar animaciones temporalmente dispares

Antes de que dos animaciones cualesquiera puedan fusionarse para correr de forma síncrona, necesita hacer que todas las animaciones usen el mismo número de fotogramas, y usen el mismo conjunto de retardos de tiempo. Cuán difícil sea la fusión depende realmente de cuán dispares sean las temporizaciones de la animación. Si los retardos de tiempo son básicamente constantes, puede simplemente ignorarlos y corregir las temporizaciones más tarde. Un ejemplo en el que el tiempo podía ignorarse al fusionar una animación de 2 fotogramas con una animación de 6 fotogramas se dio en una discusión de los foros de IM. Además, si el tiempo total del ciclo es muy diferente, puede que necesite ajustar las cosas para que una animación haga 2 o 3 bucles, de modo que llene el tiempo de ciclo de la otra animación. Básicamente, lo que importa es la temporización.

Probablemente algo como... * + Averiguar y ajustar las animaciones a un tiempo de ciclo de bucle total común * + Combinar (coalesce) ambas animaciones para eliminar cualquier optimización de fotogramas. * * Convertir los retardos de tiempo de fotograma en tiempo-desde-el-inicio de la animación. * * Duplicar fotogramas según corresponda para sincronizar en el tiempo. * * Convertir el tiempo-desde-el-inicio de vuelta en retardos de tiempo de fotograma. * + Superponer los fotogramas combinados y sincronizados en el tiempo como se desee. * + Fusionar de forma óptima y eliminar cualquier fotograma de 'retardo cero'. * + Re-optimizar la nueva animación.

Las partes con '*' podrían convertirse en un único nuevo método de "[-layer](https://imagemagick.org/command-line-options/#layers)" para sincronizar en el tiempo las dos animaciones con duraciones de tiempo de ciclo total similares.

En construcción

Ejemplo, temporalmente dispares, pero con el mismo tiempo de ciclo...

Por ejemplo, suponga que tiene dos animaciones de tres fotogramas con retardos de tiempo de
    10  10  10
    5    5  20

Ambas animaciones duran ya 30 unidades de tiempo, así que eso no es un problema.

Ahora aplique magick lo anterior al índice de tiempo en que cada fotograma debe aparecer...
y muestre la línea de tiempo global en la que los fotogramas aparecen...
   0        10    20   |__ NOTE que ambas animaciones
   0   5    10         |   terminan o hacen bucle a los 30

A partir de esto puede ver que necesita insertar algunos fotogramas extra para que
coincidan.  El primer fotograma de la primera animación necesita repetirse en el índice
de tiempo 5

0->5  10  20
0  5  10

Y el último fotograma de la segunda animación también necesita duplicarse en el
índice de tiempo 20

0->5  10  20
0  5  10->20

La flecha '->' en lo anterior significa que el mismo fotograma simplemente se repite (duplica)
en el siguiente índice de tiempo. En realidad son la misma imagen.

Ahora que las temporizaciones de los fotogramas en ambas animaciones son las mismas, puede
simplemente fusionar (componer) los fotogramas juntos, para obtener una animación final que
tiene 4 fotogramas de longitud.

Los cuatro fotogramas tendrán así retardos de tiempo de
5  5  10  10
que aún suman 30 unidades de tiempo (tiempo total por ciclo de bucle)

Estado actual del desarrollo....

Aunque IM puede ayudar a reunir información de retardo de tiempo (pruebe la opción '-t' de
"gif2anim") y construir la animación. IM no puede realizar la sincronización de tiempo
necesaria para dos animaciones combinadas separadas.  Esto puede convertirse en una
opción incorporada especial.

Es decir, necesitará averiguar y duplicar los fotogramas combinados de animación
apropiados, para cambiar dos animaciones temporalmente dispares en dos animaciones
sincronizadas en el tiempo.

Una vez que tenga las animaciones sincronizadas en el tiempo, puede entonces simplemente usar el
nuevo método "-layers Composite", para superponer o fusionar las dos animaciones
sincronizadas en el tiempo, muy fácilmente.

Todo lo anterior, sin embargo, asume que el tiempo de bucle total de las dos animaciones
es al menos aproximadamente igual, o no una preocupación importante.


**Solución simplificada**

Una solución simplificada y limitada ha sido [discutida en los foros de IM](https://magick.imagemagick.org/viewtopic.php?p=50325), para usar con animaciones que cambian rápido (símiles).

La solución toma cada animación y la expande de modo que la animación tenga
una tasa de fotogramas fija.  Es decir, todos los fotogramas se duplican de modo que cada fotograma se
muestra durante un valor constante de 6 centisegundos cada uno.  Por ello, un fotograma con un retardo de 22cs
puede ser reemplazado por 4 fotogramas de 6cs (24cs en total).

Después de esto, las animaciones se modifican aún más de modo que las animaciones cortas se
repiten en bucle varias veces para que las dos animaciones tengan finalmente la misma longitud.
Es decir, las dos animaciones se hacen de la misma longitud global en términos tanto de
tiempo, como de número de fotogramas.

Una vez que ambas animaciones tienen la misma tasa de fotogramas y la misma longitud, se puede usar la [composición de capas](#composite) para fusionar/superponer las dos
animaciones, en la posición correcta.

El resultado puede entonces optimizarse usando [Eliminar fotogramas duplicados](anim_opt.html#removedups) para eliminar cualquier fotograma extra no deseado (con
ajustes de temporización apropiados y otras [optimizaciones](anim_opt.html#intro) aplicadas antes de guardar.

Este método de tener todas sus animaciones componentes en una forma de longitud de fotograma fija
es especialmente adecuado para las bibliotecas de animaciones.


-----
Otros ejemplos por crear....
  * Superponer dos animaciones en movimiento de igual tiempo en una sola animación
    (mariposas bailando, átomos en órbita, ¿o pájaros?)
    Esto debería ser una composición de capas directa.

  * Superponer una animación en movimiento sobre un fondo fijo.
    (desplazar la animación linealmente con el tiempo)

  * Superponer dos animaciones con diferentes números de fotogramas pero retardos de tiempo
    constantes (vea [Discusión de los foros de IM](https://magick.imagemagick.org/viewtopic.php?t=12573)).

  * Superponer dos animaciones temporalmente dispares (como se esbozó arriba)

  * Superponer una figura animada sencilla, sobre un fondo animado.
    (fusión de animación completa)