⚠️ Este é um site de tradução não oficial, sem relação com a ImageMagick Studio LLC. Para informações oficiais, consulte a página original (https://usage.imagemagick.org/anim_mods/index.html).

Exemplos do ImageMagick -- Modificações de Animação

Prefácio e Índice dos Exemplos do ImageMagick
Modificações Simples de Animações

Esta página contém exemplos práticos de trabalho com animações GIF. É altamente recomendável que você leia e compreenda os Fundamentos de Animação e, ao menos, o tratamento geral da Otimização de Animações GIF antes de tentar entender estes exemplos.


Modificações Simples de Animações

Primeiro, um ponto importante

NÃO salve diretamente em GIF as animações intermediárias que você ainda não terminou de processar, especialmente imagens sobre as quais você ainda não realizou nenhum tipo de Tratamento de Semitransparência ou Otimização de Cor. Se você cometesse o grande erro de salvar em GIF, teria apenas piorado a animação resultante, pois o IM já teria realizado uma Quantização de Cores automática para reduzir o número de cores presentes e ajustar as imagens ao formato GIF limitado. Não só isso, mas o fez em cada quadro de forma completamente separada de todos os outros quadros, produzindo diferentes seleções de cor e padrões de pontilhamento. Isso, por sua vez, torna qualquer processamento posterior, em especial qualquer Otimização de Quadros, muito mais difícil. Isso é especialmente importante para animações GIF redimensionadas, ou aquelas em que você adicionou uma sobreposição ou um fundo multicolorido, pois isso pode acrescentar muitas cores extras. Você pode usar o formato interno do IM, o MIFF, como formato de arquivo temporário, se quiser trabalhar em uma animação por etapas, ou usar imagens PNG individuais para cada um dos quadros que estão sendo editados. Apenas não faça o salvamento final em GIF a menos que tenha certeza de que não terá problemas de cor. Repito...

Não use GIF como formato de arquivo intermediário; use MIFF ou imagens PNG.

Anotar - adiciona um aviso de direitos autorais sobre TODOS os quadros

A partir da versão 6.2.6 do IM, você pode "[-annotate](https://imagemagick.org/command-line-options/#annotate)" uma animação, de maneira semelhante à detalhada em Anotar sobre Imagens, simplesmente fazendo isso. Por exemplo, aqui anotamos a animação de supressão previous criada em Fundamentos de Animação. |

  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]

A razão de isso funcionar é que "[-annotate](https://imagemagick.org/command-line-options/#annotate)" posiciona o texto em relação à tela virtual de uma imagem, e não em relação aos dados reais da imagem. Assim, a posição do texto em cada quadro fica correta para uma imagem animada. Antes da versão 6.2.6, porém, "[-annotate](https://imagemagick.org/command-line-options/#annotate)", como muitos outros operadores de imagem, posicionava informações e sobreposições em relação à imagem real e ignorava qualquer deslocamento de página ou de tela virtual que um subquadro pudesse ter. Um aviso: desenhar sobre uma animação desta forma, sem antes coalescer a animação, pode causar alguns efeitos incomuns, devido ao esquema de otimização existente da animação (veja o próximo conjunto de exemplos). Por isso (e como você verá), recomenda-se remover primeiro quaisquer otimizações de quadro e de transparência existentes, coalescendo a animação.

Desenhar - modifica uma animação coalescida

Agora, embora "[-annotate](https://imagemagick.org/command-line-options/#annotate)" posicione o texto em relação à tela virtual de cada quadro, muitas outras operações de imagem não fazem isso. Isso inclui todas as operações "[-draw](https://imagemagick.org/command-line-options/#draw)", que só desenham em relação à imagem real e ignoram completamente qualquer deslocamento que ela possa ter em uma tela maior. Por exemplo, aqui desenhamos um vistoso círculo verde perto do canto superior esquerdo da animação de supressão previous. |

  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]

Bem, como você pode ver, "[-draw](https://imagemagick.org/command-line-options/#draw)" desenhou o círculo em relação à 'imagem real', em vez da tela virtual (de página) maior da qual a imagem faz parte. O resultado é, como é típico nesse tipo de situação... uma bagunça. A solução simples para isso é primeiro coalescer a animação, antes de desenhar, e então reotimizar a animação GIF em seguida. Veja Otimização de Animações para detalhes. |

  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 como o otimizador de animação do IM na verdade decidiu simplesmente não sobrescrever a parte sobre a qual se desenhou. Isso é, de fato, mais ótimo do que se tivesse desenhado nas próprias imagens de subquadro. Este método permite sobrepor qualquer tipo de anotação, aviso de direitos autorais ou marca d'água que você quiser. É claro que talvez seja necessário usar a técnica especial de Composição em Camadas para de fato sobrepor uma imagem a todos os quadros de uma animação. Se você ficar realmente bom, pode até chegar a fazer Fusão de Animações para sobrepor um aviso de direitos autorais animado à sua animação. | _Embora esta técnica de 'coalescer e otimizar' funcione com a maioria das operações que envolvem animações, especialmente com o otimizador do IM, há algumas operações que fazem mudanças tão drásticas nas imagens, como grandes alterações de cor, sombreamentos e semitransparência, que a animação resultante acaba não otimizando muito bem.

Por exemplo, praticamente qualquer operação "[-resize](https://imagemagick.org/command-line-options/#resize)" provavelmente produzirá uma animação que otimizará muito mal depois, devido a grandes mudanças de cor. Veja Redimensionamento de Animações abaixo para soluções para isso.

_
---|---

Quadro a Quadro - modificar um quadro por vez

Usando os Operadores de Lista ou Sequência de Imagens do IM, você pode modificar cada quadro da animação separadamente. O truque é extrair cada quadro entre parênteses, modificá-lo e, depois, substituir a imagem original pela versão modificada. Por exemplo, aqui adicionamos texto como marca d'água de direitos autorais na animação, na forma da própria animação, tornando-o ainda mais difícil de remover. Para não destruir completamente a animação, também usei cores 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 o uso de Parênteses para limitar o efeito da operação "[-annotate](https://imagemagick.org/command-line-options/#annotate)" a apenas um simples 'clone' de um quadro da animação. A imagem modificada é então devolvida à sua posição correta na sequência de imagens usando os operadores Swap e Delete. O uso de um único número no operador "[-swap](https://imagemagick.org/command-line-options/#swap)" foi adicionado no IM v6.3.4-3. Antes disso, você precisaria especificar "-swap 3" como "-swap -1,3" para que funcionasse corretamente.
Esta técnica de modificar quadros individuais será provavelmente uma das técnicas mais importantes que você encontrará na manipulação de animações. Você também vai notar que, na verdade, adicionei o mesmo texto tanto à primeira quanto à segunda imagem. A primeira imagem da animação acima é um Quadro Intermediário com Atraso Zero, usado para definir o fundo do restante desta animação. Ou seja, ela passa tão rápido que normalmente não é visível para os usuários, nem se destina a ser visível. Assim, os dois primeiros quadros reais da animação acima devem ser considerados um único quadro visível, e não dois quadros separados. O quadro com um atraso de tempo diferente de zero é o último quadro de uma sequência de 'exibição'. De modo semelhante, para outras animações que rodam depressa, talvez seja necessário modificar vários quadros para que sua alteração fique visível por um período apreciável. Isso não é problema para uma anotação estática que foi desenhada sobre todos os quadros (veja o exemplo anterior de Anotar acima). Isso nos leva a um ponto importante sobre animações GIF.

Estude uma animação antes de tentar modificá-la. Isso pode fazer uma GRANDE diferença no resultado final.

Recortar - limitar a área da animação

O IM se esforçou para fazer a operação de imagem "[-crop](https://imagemagick.org/command-line-options/#crop)" funcionar corretamente em relação à tela virtual de uma imagem, em vez da imagem real (a partir da versão 6.1.1 do IM). Isso, por sua vez, permite fazer coisas que antes não eram diretamente possíveis. Por exemplo, recortar as imagens de uma animação GIF e ainda assim tê-la funcionando como esperado para todas as animações. |

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

[IM Output]

[IM Output]
Como você pode ver, o recorte funcionou, tal como funcionaria para o recorte de uma única imagem, preservando o deslocamento e o tamanho de página apropriados, de modo que os dados da imagem continuam posicionados corretamente, mesmo que a área envolvida tenha sido reduzida. Como você pode ver, isso não alterou o tamanho geral da tela virtual! | Não use "[+repage](https://imagemagick.org/command-line-options/#repage)" para remover os deslocamentos de recorte de uma animação GIF com otimização de quadros. Fazer isso também removeria os deslocamentos de quadro necessários, que posicionam os subquadros na tela virtual e dos quais os quadros posteriores podem depender para animar corretamente. ---|---
A operação "[-crop](https://imagemagick.org/command-line-options/#crop)" acima, no entanto, produziu uma mensagem de aviso...

[IM Text]

Como o recorte de um dos quadros da animação não atingiu a imagem de sobreposição do subquadro usada naquele quadro. Ou seja, um quadro não atualizou a área que foi recortada da animação. Como resultado, esse quadro agora não contém nenhuma imagem real! Para compensar, o IM não só produz uma mensagem de aviso, como também gera uma 'Imagem Perdida' especial como marcador na animação, para manter tudo em ordem e preservar quaisquer métodos de 'delay' ou 'disposal' associados àquele quadro. Você pode deixar esse marcador ou corrigi-lo como preferir. Neste caso, a 'Imagem Perdida' é necessária para a animação rodar como esperado. No entanto, se várias imagens perdidas consecutivas forem geradas, você provavelmente pode fundi-las em uma única imagem perdida usando o método '[RemoveDups](anim_opt.html#removedups)' de "[-layers](https://imagemagick.org/command-line-options/#layers)". Ainda assim, recomenda-se cautela e estudo da animação. (Veja Dividir uma Animação abaixo, para um exemplo mais detalhado disso.

Recortar Também a Tela - recorte de viewport da animação

Assim como um recorte normal preservou a tela virtual das imagens originais, o mesmo aconteceu com o recorte de uma animação. Provavelmente não é essa a intenção neste caso. Por causa disso, na versão 6.2.4-5 do IM, um sinalizador especial '!' foi adicionado ao argumento de "[-crop](https://imagemagick.org/command-line-options/#crop)". Esse sinalizador faz o recorte não só recortar os quadros de imagem individuais, mas também ajustar as informações de página ou tela da imagem para essa mesma área. Isso é conhecido como 'recorte de viewport', pois o resultado será como se você estivesse olhando a imagem através de uma 'janela' ou 'viewport' do tamanho e da posição do argumento de recorte. Não só o tamanho da tela virtual é definido para o tamanho da área de recorte, como o deslocamento de cada quadro da animação é ajustado para manter tudo correto. (Veja Recorte de Viewport com Ajustes de Tela/Página). Por exemplo, vamos repetir o recorte anterior, mas também recortar as informações de tela usando o sinalizador '!'... |

  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]
| O caractere '!' tem um significado especial em alguns shells UNIX, como o "csh", e precisa ser escapado com uma barra invertida, mesmo quando colocado entre aspas. O IM ignora barras invertidas em argumentos de geometria, então não custa nada sempre colocá-la. ---|---
Como você pode ver, o resultado é mais parecido com o que você provavelmente queria de fato ao recortar uma imagem animada. Observe que incluí a configuração "[-quiet](https://imagemagick.org/command-line-options/#quiet)" para pedir ao IM que não emita a mensagem de aviso sobre a Imagem Perdida que geramos na tentativa de recorte anterior. Isso é recomendável sempre que recortar animações, pois o aviso não se aplica realmente. Observe que um Recorte de Viewport também permite aumentar a área da tela ou até reposicionar tudo dentro da tela. No entanto, é perigoso, pois quaisquer imagens que fiquem parcial ou completamente fora da área de recorte serão cortadas para mostrar apenas a parte da imagem que aparece dentro dessa área. Só mais um aviso final. Ao usar um 'recorte de viewport', as imagens dos quadros são movidas na direção negativa em relação ao deslocamento dado para o 'viewport'. Isso pode parecer ilógico, a menos que você se lembre de que o deslocamento no operador de recorte é a posição do viewport, e não um reposicionamento direto das próprias imagens.

Aparar aos Limites - correção automática do tamanho da tela

Como nas operações anteriores, aparar uma animação pode ser complicado. Se a animação consiste em uma simples Animação de Quadros Apagados, então você pode aparar uma animação simplesmente calculando os limites máximos de todos os quadros individuais da animação. A partir do IM v6.3.4-8, você pode fazer isso muito facilmente usando um método de camada 'TrimBounds'.

  magick anim_bgnd.gif -layers TrimBounds anim_trim_bounds.gif

[IM Output] [IM Output]

Para usuários de versões do IM anteriores a esta, você ainda pode fazer a mesma coisa, mas apenas em um processo de duas etapas (que também executa outro processamento indesejado). Para isso, você usaria uma Fusão de Camadas para fundir todos os quadros de uma animação em uma única camada, e então faria o IM informar o tamanho e o deslocamento dessa camada...

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

[IM Text]

Agora que você conhece os limites de todos os quadros, basta fazer um Recorte de Viewport de toda a animação para esse tamanho.

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

[IM Output] [IM Output]

Se você também quiser aparar um fundo estático de uma animação, sua melhor opção é excluir o primeiro quadro de uma animação com Otimização de Quadros, antes de usar a etapa de Fusão de Camadas. Você pode então usar os limites retornados para o Recorte de Viewport da animação original.

Reposicionar Quadros

Uma operação semelhante e relacionada é o operador de 'repage relativo'. Ele adiciona o deslocamento informado a todas as camadas de subquadro individuais da animação, permitindo ajustar suas posições em relação a toda a tela. Para tornar uma operação "[-repage](https://imagemagick.org/command-line-options/#repage)" relativa, você também adiciona um sinalizador '!' ao seu argumento. Por exemplo, aqui deslocamos o segundo quadro e os posteriores de uma animação 30 pixels para baixo e para a direita, retornando o primeiro quadro de 'fundo' à sua posição 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]


| A animação acima falhará (mostrando apenas os dois primeiros quadros) no Windows Internet Explorer versão 8. Isso acontece sempre que um quadro tenta desenhar uma imagem além dos limites da tela da animação. ---|---
Observe que nenhuma das imagens foi 'recortada' ou cortada. Apenas suas posições foram alteradas, em relação à imagem de fundo original, mesmo que a imagem tenha sido movida 'para fora da tela'. Se quiser, você também pode expandir a tela para corresponder a esses novos limites, seja ajustando o tamanho da tela diretamente... |

  magick repage_offset.gif -repage 130x130  repage_canvas.gif

[IM Output]
Usando o Método de Camada Trim Bounds, você pode expandir automaticamente os limites da animação apenas o suficiente para incluir as imagens que agora estavam sendo colocadas 'fora dos limites'... |

  magick repage_offset.gif -layers TrimBounds repage_bounds.gif

[IM Output]
| _Usar "[-repage](https://imagemagick.org/command-line-options/#repage)" para mover imagens para a esquerda ou para cima, especialmente com uma tela pequena, provavelmente falhará em animações GIF. Este formato basicamente não pode usar um deslocamento de imagem negativo.

Para isso, talvez seja melhor você também aplicar um 'recorte de viewport', ou usar o 'trim bounds' para deslocar todos os deslocamentos para uma tela positiva maior. Qualquer um dos métodos garantirá um deslocamento positivo para todos os quadros de imagem.

Os formatos PNG e MNG conseguem lidar com deslocamentos negativos, mas muitos navegadores web e outros programas podem não entender tais deslocamentos, produzindo efeitos estranhos. Uma versão do navegador "Firefox", por exemplo, produz imagens extremamente grandes ao tentar exibir um PNG com um deslocamento negativo._ ---|---

Inverter Animações - fazer animações rodarem de trás para frente, ou em ciclo

A partir do IM v6.3.3, o operador de sequência de imagens "[-reverse](https://imagemagick.org/command-line-options/#reverse)" foi adicionado (veja Operador Reverse para mais detalhes). Ele permite inverter de forma muito simples a ordem de uma sequência de animação coalescida. Por exemplo, aqui faço uma animação de 'k desenhado à mão' ser 'desdesenhada'! |

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

[IM Output]
Tive de readicionar a opção "[-loop](https://imagemagick.org/command-line-options/#loop)" acima, pois ela precisa estar associada à primeira imagem, que agora é a última imagem! O resultado também poderia usar alguns ajustes de tempo, mas, como você pode ver, agora ele 'desdesenha' a letra! Certifique-se de "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)" a sequência de imagens antes de invertê-la, pois quaisquer Otimizações de Quadros presentes dependem da ordem das imagens. É melhor remover essas otimizações primeiro.

Ciclos de Patrulha - alternar de um extremo ao outro

Uma técnica semelhante é adicionar uma ordem invertida de quadros ao final da animação, de modo que a animação resultante alterne entre o primeiro e o último quadros da animação original. É um pouco como um guarda fazendo uma patrulha entre dois pontos, e é chamado de 'Ciclo de Patrulha'. Aqui uso o Operador Duplicate de imagem (adicionado ao IM v6.6.8-7) para gerar os quadros extras (invertidos). |

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

[IM Output]
Observe que não copiei simplesmente todas as imagens da animação, mas deixei de copiar a primeira e a última imagem da sequência original. Se eu tivesse copiado todas as imagens, a primeira e a última apareceriam pelo dobro do tempo esperado, e tornariam o arquivo da animação maior do que o necessário. Ainda assim, você deve novamente ficar atento a Quadros Intermediários com Atraso Zero no início e no fim da animação, pois eles podem resultar em problemas inesperados. Basicamente, não faça isso sem antes estudar a animação, ou estará pedindo por problemas. Além disso, para permitir uma melhor otimização do resultado, talvez você precise até adicionar alguns Quadros Intermediários com Atraso Zero extras, entre os ciclos de ida e de volta, para melhorar a otimização. Esses quadros extras provavelmente não foram fornecidos na otimização da animação original, pois toda a animação normalmente se reinicia quando entra em laço. Veja Dividir Atualizações de Quadro para mais detalhes de como esses quadros extras ajudam a otimizar e melhorar a animação. Aqui está um método mais antigo, usando o Operador Clone para gerar quadros duplicados. |

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

[IM Output]

Morphing de Cor - mudança animada entre duas imagens

O operador "[-morph](https://imagemagick.org/command-line-options/#morph)" é um operador especialmente interessante. Ele pega uma lista de imagens e insere quadros extras entre elas, de modo a fazer uma suave mudança de cor de uma imagem para a próxima. Este operador, porém, não é um verdadeiro 'morph', pois só modifica a cor dos pixels, criando uma sequência de Imagens Mescladas. Um verdadeiro 'morph' cinematográfico também envolve Distorção de imagem, para transformar o contorno do objeto de uma imagem nos objetos da outra. Por exemplo, aqui crio um Ciclo de Patrulha usando um morph de cor para gerar os quadros extras entre a imagem da rosa e sua forma espelhada. |

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

[IM Output]
Isso não é particularmente bom, pois todas as imagens têm o mesmo atraso. O resultado é que a animação nunca parece 'descansar' ou pausar entre os dois pontos extremos do ciclo. Uma solução melhor seria ter uma pausa na imagem original e em sua forma 'espelhada'. Isso, porém, exige que você ajuste os atrasos das imagens originais para serem diferentes dos das imagens de morphing. |

  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 você pode ver, os atrasos de tempo podem se tornar muito importantes para gerar boas animações, permitindo que a animação 'descanse' exatamente nos pontos certos. A partir do IM v6.6.9, você pode definir o atraso usando um Escape de Porcentagem FX que calcula com base no índice da imagem. Aqui, a expressão FX diz para usar um atraso de 10 se o índice da imagem não for o primeiro (t=0) nem o último (t=n-1); caso contrário, usar um valor maior. |

  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 uma variedade de métodos diferentes de 'morphing' ou de fazer uma 'transição' de uma imagem para outra, veja os scripts de shell do ImageMagick "[transitions](http://www.fmwconcepts.com/imagemagick/transitions/)" e "[fxtransitions](http://www.fmwconcepts.com/imagemagick/fxtransitions/)", de Fred Weinhaus. A página de Exemplos inclui o algoritmo básico que o script usa para gerar a animação.

Morphing de Redimensionamento - mudança animada de tamanho

O Operador de Morph de Cor na verdade não só faz a mescla de cores entre duas imagens, como também redimensiona a imagem ao mesmo tempo. Por exemplo, aqui uso "[-morph](https://imagemagick.org/command-line-options/#morph)" em duas imagens de tamanhos diferentes, e até com proporções 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]
Apenas a primeira linha faz o morph de redimensionamento. Se você olhasse as imagens reais, cada quadro teria um tamanho diferente! As duas linhas seguintes 'preenchem' as imagens para que fiquem do mesmo tamanho, preenchendo as partes não usadas com preto. Especificamente, a operação foi concebida de modo que a ordem das imagens não importe. O restante serve apenas para montar um Ciclo de Patrulha e os atrasos de tempo associados. O 'redimensionamento' é realizado apenas a partir do canto superior esquerdo. No momento em que este texto foi escrito, o Operador de Morph de Cor não entende deslocamentos de camada, nem qualquer outro morphing espacial (morphing com distorção). Assim, se você quiser que o redimensionamento seja centralizado, talvez precise usar técnicas muito mais complexas mostradas em seções posteriores. Aqui está um exemplo semelhante, desta vez redimensionando a imagem com uma versão menor da mesma imagem (proporção preservada)... |

  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]
Observe que as imagens 'intermediárias' ficam mais borradas do que provavelmente deveriam. Isso acontece porque a imagem maior não está apenas sendo redimensionada para menor, mas também sendo mesclada em cor com a imagem menor que foi redimensionada para maior.

Wipe - criar uma varredura de uma imagem para outra

Na verdade, isso é muito fácil de fazer. Basta sobrepor 'fatias' da nova imagem. Elas são geradas diretamente usando um simples Recorte em Ladrilhos. Por exemplo, aqui fazemos uma 'varredura' de uma imagem para sua versão espelhada e, só por diversão, voltamos com a varredura de novo. |

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

[IM Output]
Aqui está uma versão de GeeMack, dos Fóruns do IM, que implementa varreduras a partir das quatro direções... |

  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]

Distorções Animadas - distorcer várias imagens com base no índice da imagem

Muitos operadores podem usar Escapes de Porcentagem em seus argumentos. Isso significa que você pode, na verdade, modificar o operador para que ele atue de forma ligeiramente diferente para cada imagem que está sendo processada. O método envolve primeiro Duplicar Imagens para criar 30 (ou quantas você quiser) cópias idênticas da imagem da rosa. Você então modifica cada imagem de forma diferente usando Escapes de Porcentagem FX para calcular valores de distorção, com base no índice da imagem '%[fx:t]' e no número de imagens da lista '%[fx:n]'. Por exemplo, aqui transladamos a imagem por uma quantidade 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]
E aqui giro a imagem, dependendo do índice, mas gero uma pausa mais longa quando o índice da imagem é 0 (a primeira imagem). |

  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]
Observe que o índice da imagem ('t') tem um valor de '0' a 'n-1', de modo que a fórmula '%[fx:t/n]' terá um valor de '0.0' a um valor pouco antes de '1.0'. Isso é perfeito para uma animação repetitiva ou cíclica como a acima, mas pode não ser muito bom para gerar transições de uma imagem para uma nova imagem. Nesse caso, você quer que o quadro final tenha um multiplicador de '1.0' no último quadro; use a fórmula '%[fx:t/(n-1)]'. Isto é apenas uma amostra do que agora pode ser feito facilmente usando índices de imagem em cálculos '%[fx:...]'. Imagine o que é possível com distorções mais complexas. Sem o uso de cálculos com índice de imagem, o acima teria exigido um laço externo de shell, para gerar cada quadro individualmente, e uma etapa separada para reunir os quadros e formar a animação final. Exemplos de tais scripts de shell com laço são dados em Animações Simples de Imagens Deformadas, pois esses operadores não permitem o uso de Escapes de Porcentagem em seus argumentos. | Antes do IM v6.6.9-0, os Escapes de Porcentagem e os Escapes de Porcentagem FX envolvendo índices de imagem, como '%p', '%n', '%[fx:t]' e '%[fx:n]', estavam quebrados. Normalmente, retornavam apenas valores inúteis de '0' ou '1', e não o índice real e o número de imagens da sequência de imagens atual. ---|---

Anexar um Rótulo - adicionar um rótulo a toda a animação

Como sempre, há várias maneiras de, de fato, anexar um rótulo a uma imagem. Por exemplo, para animações que têm uma tela de fundo inicial, ou que apenas sobrepõem nova cor aos quadros anteriores, você pode simplesmente anexar o rótulo ao primeiro quadro da imagem. Os outros quadros não o removerão. Aqui, apenas adicionamos algum espaço extra com "[-splice](https://imagemagick.org/command-line-options/#splice)" e "[-annotate](https://imagemagick.org/command-line-options/#annotate)" algum texto nele. |

  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]
No entanto, isso só funciona para algumas animações. Não funcionaria para uma Animação de Quadros Apagados comum, que apaga ou substitui todos os pixels após cada quadro ser exibido. Para um método mais geral que funcione com todas as animações, precisamos primeiro "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)" a animação para a Animação Coalescida não otimizada. Então podemos adicionar o rótulo a todos e cada um dos quadros coalescidos da animação, antes de reotimizá-la. |

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

[IM Output]
Em vez de usar "[-annotate](https://imagemagick.org/command-line-options/#annotate)" para desenhar texto no espaço extra adicionado, você pode usar um método de composição (veja as próximas seções) para compor uma imagem no espaço adicionado. Assim, você pode preparar um rótulo bem mais elaborado para adicionar à animação. É claro que fazer isso pode fazer com que algumas animações não otimizem muito bem depois, especialmente as Animações de Quadros Apagados, mas esse é o preço que se paga por adicionar rótulos. Uma solução para esse tipo de animação é anexar no início uma 'tela de fundo inicial' que contenha o rótulo, como mostrado na seção que explica as Animações de Quadros Apagados. Note também que adicionar um rótulo a uma animação pode resultar em muitas cores extras adicionadas. Isso poderia estourar os limites de cor do GIF, de modo que talvez você tenha de estar preparado para também otimizar a cor da sua animação. Uma tarefa muito difícil, que é melhor evitar se possível (veja Otimização de Cor). Isso pode ser um problema para qualquer modificação geral em qualquer animação.

Remover Transparência - adicionar um fundo de cor sólida

Um grande número de animações que você encontra na web tem um fundo transparente. Elas são muito úteis, pois você pode colocá-las em páginas web sem precisar se preocupar com qualquer padrão de fundo que possa estar presente. No entanto, ao processar animações, especialmente ao aplicar outros operadores de imagem como "[-resize](https://imagemagick.org/command-line-options/#resize)" e "[-blur](https://imagemagick.org/command-line-options/#blur)", tal animação apresenta problemas. A solução geral é Remover Transparência da imagem, geralmente sobrepondo-as de algum modo a uma cor específica, como a cor específica usada como fundo de uma página web. [IM Output] Por exemplo, aqui tenho uma simples animação de sobreposição transparente de uma letra 'K' sendo desenhada como que por uma mão invisível. Como esta animação GIF é desenhada com transparência e só sobrepõe imagens aos quadros anteriores (adicionando pixels, nunca removendo-os), uma maneira simples de definir uma cor (ou imagem) de fundo é adicioná-la apenas ao primeiro quadro da animação. Todos os outros quadros contêm uma cor transparente para o fundo, portanto não afetarão o resultado. Aqui usamos o Operador de Achatamento para sobrepor o primeiro quadro da animação a uma cor de fundo 'LimeGreen'. Podemos usar "[-flatten](https://imagemagick.org/command-line-options/#flatten)" para isso, pois estamos aplicando-o apenas a uma única imagem, e NÃO a toda a animação. |

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

[IM Output]
Também é importante notar que o primeiro quadro original tinha apenas um pixel de tamanho. O Operador de Achatamento não só coloriu o fundo, como também expandiu esse quadro ao seu tamanho completo. Ou seja, também 'preencheu' o quadro. Note, porém, que apenas o primeiro quadro da animação foi colorido. Este método é preferível, pois qualquer otimização (como a otimização pesada que esta animação contém) é preservada. Colorir o primeiro quadro não funcionará com todas as animações GIF. Só funciona com simples Animações de Sobreposição. Para um método geral de remover a transparência de uma animação, você precisa primeiro "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)" a animação e, então, de fato Remover Transparência de todos os quadros, usando o Operador de Remoção de Alfa. Desta vez, vamos fazer isso usando uma cor de fundo 'Tomato'. |

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

[IM Output]
É claro que a otimização resultante pode não ser tão ótima quanto a original, mas a animação não tem mais nenhuma transparência. Como efeito colateral adicional, quaisquer configurações de supressão '[Background](anim_basics.html#background)' da animação terão sido convertidas para '[None](anim_basics.html#none)' ou '[Previous](anim_basics.html#previous)', pelo processo de Otimização de Quadros, já que a transparência não é mais uma questão. | A Remoção de Alfa foi adicionada ao IM v6.7.5. Se a sua versão do IM for mais antiga, você precisará usar um método alternativo, como o efeito colateral do Operador de Borda. Veja Remover Transparência para detalhes deste e de outros métodos. ---|---
Um tratamento de fundo mais complexo, como colocar por baixo uma imagem ou padrão de fundo, exige um tratamento de animações muito mais complexo do que as modificações simples que examinamos até agora. É isso que veremos a seguir.


Composição Alfa de Múltiplas Imagens

O próximo nível de tratamento de animações exige que você seja capaz de compor imagens estáticas únicas sobre, ou sob, uma animação existente. Ou seja, Composição Alfa geral. Isso fica ainda mais complicado quando dois conjuntos separados de imagens estão sendo fundidos. Antes do IM v6.3.3-7, a composição de múltiplas listas só era possível usando scripts de API especialmente projetados, ou scripts de shell que salvavam e fundiam os quadros individuais da animação. Nenhuma era uma técnica muito boa, mas era tudo o que se podia fazer. Isso, agora, mudou.

Desenhar Imagens - desenhar uma imagem sobre uma lista de imagens

O operador "[-draw](https://imagemagick.org/command-line-options/#draw)" tem a capacidade de compor uma imagem de origem sobre uma lista de imagens. É também o único método de composição alfa de múltiplas imagens que você poderia usar no comando "[mogrify](basics.html#mogrify)", ou contra várias imagens, antes do IM v6.3.3-7. A razão pela qual esta técnica de Composição Alfa era tão importante é que ela permitia especificar uma imagem como um argumento separado da lista de imagens atual. Ou seja, dentro da linguagem Magick Vector Graphic entre aspas de "[-draw](https://imagemagick.org/command-line-options/#draw)". Por causa de sua importância histórica, mostrarei seu uso em detalhe, especialmente para usuários que ainda têm versões mais antigas do IM. Por exemplo, aqui sobreponho a imagem da rosa sobre toda a animação. |

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

[IM Output]
Isso permite Compor uma imagem de origem externa sobre cada imagem da sequência de imagens atual. Isso é bom o suficiente para a maioria dos propósitos. Por exemplo, usando o método de composição '[Dst_Over](compose.html#dstover)', você também poderia colocar uma imagem 'sob' a animação como um fundo estático. Por exemplo, aqui colocamos por baixo uma imagem embutida "netscape:", embora pudesse ter sido qualquer arquivo de imagem externo... |

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

[IM Output]
Observe que o tamanho da animação não mudou, pois são as imagens de destino que definem o tamanho final da composição alfa. Se você quisesse criar uma tela maior, teria de ajustar apropriadamente o tamanho e os deslocamentos da animação para acomodar o fundo. Por exemplo, usando um Repage Relativo da animação antes de coalescer. |

  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]
Além disso, se você quisesse usar uma imagem que já havia sido lida, criada ou modificada, então precisaria usar um "MPR: Registrador de Programa de Memória para lhe fornecer uma 'origem de leitura' para essa imagem. |

  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]
Esse é, mais ou menos, o limite dos métodos de Composição Alfa por Draw. Nada de sobrepor as imagens da animação 'sobre' uma imagem de destino de tamanho desconhecido, e nenhuma forma de fundir duas sequências separadas de múltiplas imagens. Isso foi assim até...

Composição em Camadas - composição alfa para listas de imagens

Com o IM v6.3.3-7, o método '**Composite**' de "[-layers](https://imagemagick.org/command-line-options/#layers)" foi adicionado, permitindo compor dois conjuntos de imagens completamente separados. (Para um breve resumo, veja Sobrepor Imagens em Camadas, Layer Composite) Para fazer isso na linha de comando, é necessária uma imagem marcadora '[null:](files.html#null)' especial para definir onde termina a primeira lista de imagens de destino e começa a lista de imagens de origem sobreposta. Mas essa é a única complicação real deste método. Então, vamos experimentar, criando um conjunto de sombras a partir de um conjunto de imagens e, depois, sobrepondo a imagem original sobre essas imagens 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]

O exemplo acima é muito importante, então vou explicá-lo em detalhe. Primeiro, geramos uma versão Coalescida da nossa animação, para remover quaisquer Otimizações que possam estar presentes e deixar a animação pronta para um processamento sério, sem que otimizações GIF interfiram no processamento. Em seguida, criamos uma imagem de sombra animada a partir da nossa animação coalescida e Removemos a Transparência, pois o GIF não consegue lidar com sombras semitransparentes. Esta é a animação que queremos adicionar 'sob' a nossa animação original. Ela tem o mesmo número de quadros e até os mesmos tempos da animação original. Essa correspondência é importante, então não a esqueça. Agora, lemos as duas sequências de animação ou de camada, mas adicionamos um separador de imagem '[null:](files.html#null)' especial entre elas, para que o ImageMagick saiba quando uma sequência termina e a próxima começa. Esse separador de imagem é removido automaticamente pela operação "-layer composite" a seguir, tão importante. Outras APIs devem poder usar 'Wands' separados de imagens, em vez de uma única sequência com um separador especial. A composição em camadas é então realizada como se essas duas animações ou sequências de imagens fossem apenas uma única imagem simples, e não uma sequência de várias imagens. Cada par de imagens, uma de destino e uma de origem, é composto em conjunto, gerando uma sequência de imagens mesclada (composta). O resultado final é que adicionamos sombras à nossa sequência de animação original, que está pronta para otimizações GIF, ou apenas para uso direto. Agora, você pode fazer todos os passos acima em um único comando. No entanto, não dá para usar apenas "[-clone](https://imagemagick.org/command-line-options/#clone)" para criar uma cópia da sequência original, já que não sabemos de fato (nem queremos saber) quantas imagens há na sequência. Em vez disso, você pode usar um "MPR: Registrador de Programa de Memória para salvar uma lista inteira de imagens. É como tirar um instantâneo de toda a sequência de imagens atualmente na memória e, depois, lê-la de novo mais tarde. O resultado é um comando como este, embora eu tenha usado um fundo de cor diferente. |

  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 versão na verdade funciona melhor, pois não perdemos a informação de deslocamento que o Operador de Sombra gera (os GIFs não conseguem salvar um deslocamento negativo, então o redefinem como zero). Poderíamos corrigir isso no exemplo acima usando o formato de arquivo MIFF para as imagens intermediárias, em vez de GIF, ou, como você verá no próximo exemplo, usando um deslocamento de composição "[-geometry](https://imagemagick.org/command-line-options/#geomtry)". Basicamente, estes exemplos mostram que o Operador Layers Composite na verdade entende as configurações individuais de Deslocamento de Tela Virtual ("[-page](https://imagemagick.org/command-line-options/#page)") e as trata, assim como os operadores Layers Flatten ou, melhor ainda, Layers Merge as tratariam. Mas o Operador Layers Composite também entende o uso de um deslocamento de Geometria de Composição ("[-geometry](https://imagemagick.org/command-line-options/#geometry)") (zero por padrão), para controlar o posicionamento geral de toda a sequência de imagens sobreposta. Ele até entende os efeitos de "[-gravity](https://imagemagick.org/command-line-options/#gravity)" nesse deslocamento global. Por exemplo... vamos sobrepor a nossa animação 'K' original ao 'Sul' da animação de sombra gerada... |

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

[IM Output]
O exemplo acima também mostra que, tal como na Composição Alfa normal de duas imagens, é a sequência de imagens de destino que controla o tamanho final da imagem de saída, e qualquer sobreposição de composição será cortada pela imagem da tela de destino. Assim, você deve garantir que todas as imagens de destino sejam grandes o suficiente para conter os seus resultados finais. | A capacidade de redimensionamento de "[-geometry](https://imagemagick.org/command-line-options/#geometry)" não faz parte, a rigor, da operação de composição; ela só redimensiona a última imagem da sequência de imagens atual. Assim, não fará o que você espera se usada com a Composição em Camadas de múltiplas imagens. Veja Geometria de Redimensionamento para detalhes. ---|---
Basicamente, a Composição em Camadas é muito parecida com a composição normal. Bem simples, na verdade. Eu disse simples? Detalhes da Composição em Camadas......Como você viu acima, a versão de linha de comando de "[-layers](https://imagemagick.org/command-line-options/#layers) Composite" usa a primeira imagem '[null:](files.html#null)' encontrada na lista de imagens atual como marcador para separar as duas listas. As duas listas de imagens são separadas e o 'null:' é descartado antes de as duas listas serem compostas por alfa, duas imagens por vez. Apenas uma imagem gerada a partir da origem de imagem '[null:](files.html#null)' especial pode ser usada como marcador e, se não for encontrada, um erro será reportado. Atualmente, você não pode ler essa imagem marcadora '[null:](files.html#null)' de um pipeline (ao menos não neste momento), apenas gerá-la quando necessário. A composição em camadas também é bem mais complexa do que uma simples Composição Alfa de duas imagens, pois a tela virtual das imagens da lista também é levada em conta. Normalmente, a composição alfa ignora qualquer tamanho e deslocamento de tela virtual para fins de posicionamento, usando apenas o tamanho real das imagens. Este método especial de camadas usa a informação da tela virtual, para o posicionamento por geometria, de modo a alinhar as duas sequências de imagens. Para esse fim, qualquer deslocamento de tela virtual que um subquadro tenha também é adicionado ao deslocamento de composição "[-geometry](https://imagemagick.org/command-line-options/#geometry)", ajustado pela "[-gravity](https://imagemagick.org/command-line-options/#gravity)" normal, para calcular a posição da sobreposição da imagem. Apenas o tamanho da tela virtual "[-page](https://imagemagick.org/command-line-options/#page)" da primeira imagem de cada lista é usado para calcular o ajuste de "[-gravity](https://imagemagick.org/command-line-options/#gravity)" ao deslocamento de composição "[-geometry](https://imagemagick.org/command-line-options/#geometry)". O tamanho da tela das imagens posteriores é ignorado, sendo apenas o deslocamento virtual "[-page](https://imagemagick.org/command-line-options/#page)" individual adicionado ao deslocamento "[-geometry](https://imagemagick.org/command-line-options/#geometry)" calculado. Em outras palavras, "[-layers](https://imagemagick.org/command-line-options/#layers) Composite" foi concebido para a composição alfa de 'camadas' ou 'animações', e para os requisitos especiais de tais listas de imagens. Ressalvas...Você, no entanto, ainda precisa ter cuidado com as listas de imagens que está sobrepondo. Se, por exemplo, as imagens da lista de destino não forem grandes o suficiente, ou estiverem posicionadas incorretamente para conter a imagem de origem sobreposta, a imagem sobreposta será cortada, ou não atingirá a imagem de destino de forma alguma. Por essa razão, é uma boa ideia Coalescer as imagens de destino ao tamanho completo da tela, antes de sobrepor imagens de origem menores. Por exemplo, veja os exemplos de Concatenação Lado a Lado de Animação abaixo, onde foi necessário expandir o tamanho da tela para dar espaço às imagens concatenadas. Além disso, se a lista de imagens de origem for uma animação GIF, então talvez você precise garantir que os subquadros estejam limpos de coisas como: Otimizações de Compressão e sofisticadas Otimizações de Quadros; ou você pode ter problemas. Por outro lado, uma Animação de Quadros Apagados ou uma Animação Coalescida pode ser diretamente '[Composta](#composite)' sem nenhum problema. Apenas lembre-se de que a Composição em Camadas não entende quaisquer Métodos de Supressão do GIF existentes que possam estar presentes nas imagens, embora preserve os metadados da animação GIF de destino, tais como: Método de Supressão, Atraso de Quadro e Limites de Iteração do Laço. A única exceção a isso é dada em um caso especial abaixo.

Composição com Imagem Única - compor imagens com uma única imagem

Normalmente, duas listas de imagens de igual comprimento são compostas em conjunto, um par de imagens por vez, até que uma das listas se esgote. Nenhuma das listas de imagens será repetida. A composição simplesmente para. Você fica apenas com a lista de imagens de destino original acrescida das composições. A imagem separadora '[null:](files.html#null)' e todas as imagens de origem são excluídas da lista de imagens atual. Uma interface de API para este método de camadas deveria permitir que você produzisse duas listas de imagens separadas, e caberá a você excluir ambas as listas de imagens de entrada usadas para gerar a lista de imagens resultante. O separador '[null:](files.html#null)' não deveria ser necessário.
No entanto, se uma das listas contém apenas uma única imagem, essa imagem será composta contra todas as imagens da outra lista. Não importa se essa imagem única é uma imagem de origem ou de destino. O método fará a composição contra a outra lista de imagens e preservará os metadados GIF da lista de imagens, e não os da imagem única, mesmo que essa imagem seja a de destino. Essa 'composição contra uma imagem única' é um caso especial da Composição em Camadas, e é muito útil para adicionar um fundo a uma animação (veja a seguir), ou para inserir um objeto estático em uma animação.

Fundo Estático - compor sobre um fundo maior

Por exemplo, usando este método especial de Composição em Camadas com Imagem Única, podemos compor uma animação sobre um fundo 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 a imagem de fundo é a de destino, ela define o tamanho final da animação, mas todos os metadados (atrasos, rótulos, comentários etc.) virão da lista de imagens de origem. Normalmente, essa informação vem da lista de imagens de destino. Esta é a única vez em que a imagem de origem fornece a informação de metadados durante uma composição de imagens. Note também que, como a Composição em Camadas entende "[-gravity](https://imagemagick.org/command-line-options/#gravity)", a imagem é devidamente centralizada, sem que você precise fazer os cálculos por conta própria. No entanto, se os quadros de origem contiverem deslocamentos, estes também serão adicionados à posição definida pela gravidade, de modo que a posição relativa de todos os subquadros permaneça correta. Note que, como a animação "[script_k.gif](../static/img/images/script_k.gif)" é, na verdade, um tipo de Animação de Sobreposição, há métodos alternativos de adicionar um fundo estático à animação. Veja a seção acima sobre Remover Transparência para um exemplo (sobre uma cor sólida, mas pode ser qualquer imagem). O mesmo vale para a ainda mais simples Animação de Quadros Apagados. Nesse caso, você nem precisa Coalescer a animação primeiro, mas pode compô-la diretamente sobre uma imagem de fundo. No entanto, talvez você precise "[-set](https://imagemagick.org/command-line-options/#set)" o método 'dispose' usado em seguida ou, melhor ainda, Otimizar a Animação Totalmente Coalescida. Contudo, qualquer outro tipo de animação otimizada exigirá aquela operação "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)" e composição completa com todos os quadros da animação. Por isso, provavelmente é melhor usar o método acima, apenas para garantir que todas as animações GIF sejam tratadas corretamente.


Nem tudo que reluz...

Animações de Brilho

Os métodos de Composição em Camadas acima tornam muito mais fácil gerar animações simples, como o brilho reluzente. Primeiro, precisamos de algum brilho grande o suficiente para cobrir a imagem que está sendo processada. Aqui, vou gerar uma animação de brilho de três imagens a partir de algumas Imagens de Pontos Aleatórios. Primeiro, isto é um brilho bruto em preto e branco sobre pura transparência, gerando 3 quadros de brilho ao separar os três canais de cor em Imagens de Canal em preto e branco. É, basicamente, um ponto de partida bruto para gerar qualquer outro tipo de brilho. O limiar de '30%' controla quantos 'pontos' há por quadro. |

  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 desse brilho 'bruto', você pode sobrepô-lo usando uma composição alfa '[Screen](compose.html#screen)' para clarear apenas alguma cor, gerando um brilho de uma cor específica. Uso o Método de Achatamento por Borda (acima). Apenas uma cor simples... |

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

[IM Output]
Usando a Composição em Camadas, você também pode usar uma única imagem, ou mesmo várias imagens, para fornecer um fundo de cor variável. Por exemplo, aqui gero três imagens de Plasma Fractal, para dar uma coloração ligeiramente aleatória ao padrão de brilho. |

  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]
É claro que há muitos outros estilos de brilho e padrões de movimento. Você pode encontrar e baixar muitos desses ladrilhos de brilho na WWW. Para aplicar um brilho como este a uma imagem, há vários métodos diferentes. Normalmente, você mascara o brilho para uma forma e/ou fundo específico. Para isso, você pode usar uma forma transparente (composta 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]

Ou uma imagem de máscara em preto e branco (composta 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]

Ok, temos uma área que foi mascarada; você pode completar a imagem, geralmente sobrepondo o brilho mascarado à imagem original. No entanto, no nosso caso, vou colocar um fundo por baixo e sobrepor uma borda. |

  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 exemplo também eliminou quaisquer problemas de transparência do GIF, ao remover toda a transparência da imagem final e sobrepor uma borda suave em torno da região com brilho. | Embora eu possa ter usado imagens em formato GIF acima para poder exibir com o magick os passos individuais do processo, na prática você combinaria todos os passos em um único comando, ou usaria um formato de arquivo de imagem intermediário melhor, como o MIFF. Isso é feito para evitar os problemas inerentes ao formato GIF, até termos terminado. ---|---

Ladrilhos de Brilho - por baixo, com 'buraco na imagem'

Como mencionado, há muitas imagens de ladrilhos de brilho animados prontos disponíveis na WWW (faça uma busca por "glitter tiles"). Uma fonte é um usuário do IM Studio, scri8e, e seu site Moons Stars. Fique avisado, porém, de que acho a maioria dos ladrilhos de brilho bastante horríveis, ou rápidos demais. Para este exemplo, encontrei e modifiquei um ladrilho de brilho azul com alguns pequenos padrões de estrela nele. Achei que seria útil para dar ao mago do IM uma roupa reluzente, deixando-o com um ar realmente mágico. Provavelmente, a maneira mais fácil de aplicar brilho a uma imagem existente é recortar buracos na imagem, em vez de tentar mascarar o padrão de brilho. Isso, porém, só funciona para imagens que não contêm transparência de início. Como alternativa, você poderia remover a transparência de uma imagem e, ao terminar, readicionar a transparência original. Então, vamos pegar o logotipo dos Exemplos do IM e usar Substituição de Cor para recortar todas as partes azuis da imagem. Uma espécie de manto de invisibilidade para o nosso mago ;-)

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

[IM Output] [IM Output]

Observe o uso do Fator de Fuzz para ajustar exatamente quanto da cor azul deve ser removido. Fique avisado, porém, de que esta não é uma boa forma de recortar uma área de uma imagem, pois produz Bordas Serrilhadas. Mas, por enquanto, ainda não há um recurso simples de recorte com bordas suavizadas. Ok, temos uma imagem com um buraco (ou muitos buracos). O próximo passo é colocar por baixo a imagem do ladrilho de brilho. O problema é que o ladrilho acima é pequeno demais, ele não cobrirá toda a imagem! O seguinte usa uma técnica engenhosa para ladrilhar o ladrilho de brilho de múltiplas imagens. No entanto, você ainda precisa dar um tamanho maior que o da imagem original, para garantir que consiga cobri-la completamente. |

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

[IM Output]
Agora, vamos vestir o nosso mago com suas novas roupas, colocando o brilho ladrilhado acima sob a imagem 'esburacada'. |

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

[IM Output]
Você pode, é claro, fazer todos esses passos em um único comando. Aqui, limito a geração de buracos apenas ao manto do mago, que tem duas 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]
Os buracos acima foram criados usando as primitivas Matte Fill de Draw para selecionar um ponto e uma cor reais da imagem para a substituição de cor. Isso significa que não preciso usar um Fator de Fuzz tão alto quanto o que usei originalmente, pois minha cor de comparação veio das áreas específicas selecionadas. Também usei um 'viewport' de ladrilho maior, para garantir que eu cobrisse completamente a imagem que está sendo ladrilhada, sem precisar saber suas dimensões exatas. | _O uso do Operador de Distorção Geral e sua opção especial "viewport' (adicionada ao IM 6.3.6-0) também lhe dá a oportunidade de modificar o padrão de distorção de outras formas especiais. Como dar-lhe um aspecto de 'perspectiva' ou girar o padrão em ângulos não retangulares. Fazer isso pode aprimorar o ladrilhamento, para que ele não tenha um aspecto tão uniforme.

Para alguns exemplos, veja Ladrilhamento Afim._ ---|---

Faíscas - sobrepor brilho quase totalmente transparente

O grande problema com as duas técnicas anteriores de animação de brilho é que são uma substituição do tipo tudo ou nada. Você não pode usar o sombreamento ou o fundo original da imagem. Além disso, o brilho fica completamente restrito à área que foi mascarada. Ele não pode se estender além dos limites da área envolvida. Assim, algumas áreas pequenas, como o 'chapéu' do mago no exemplo anterior, não lidam muito bem com o brilho. As faíscas são diferentes, pois a animação adicionada é, em sua maior parte, transparente. Como consequência, a imagem original ainda pode aparecer por baixo. Tais animações costumam ser adicionadas a uma imagem de uma de duas formas. Ou a própria sobreposição da animação é transparente, ou tem a forma de um fundo preto com 'faíscas' brancas onde a imagem deve ser clareada.

Em Construção

Aqui está um exemplo de uma sobreposição de 'faíscas' em sua maior parte transparente. Exemplo Aqui Como você pode ver, é possível ter sobreposições de faíscas coloridas quando esta forma é usada. O grande problema disso é que uma animação GIF foi usada para salvá-la (o que costuma ser o caso), então a sobreposição fica fortemente serrilhada. Ou seja, ela não pode conter nenhum pixel semitransparente para suavizar o aspecto da imagem sobreposta. Se contivesse, você teria horríveis halos pretos em torno das 'faíscas' no resultado final. Vamos mascarar e sobrepor isto ao mago. Exemplo Aqui A outra forma de faíscas é faíscas brancas sobre um fundo preto (uma imagem em tons de cinza). Elas são mascaradas e sobrepostas de modo a clarear a imagem para adicionar a faísca. Por exemplo... Exemplo Aqui Uma das melhores coisas das faíscas é que você pode gerar uma sequência de quadros em que as faíscas aparecem lentamente e depois desaparecem. Isso pode ficar bem complexo, mas não é muito difícil de fazer. Exemplo Aqui

Adicionar Animações de Alargamentos e Estrelas

Enquanto o brilho consiste em pontos únicos de luminosidade, e as faíscas podem se sobrepor a algumas áreas de uma imagem, os alargamentos costumam ser adicionados individualmente. Um 'alargamento' é, basicamente, um ponto que pisca para cobrir uma grande área por apenas um instante. Uma 'estrela' é semelhante, exceto que a cobertura tem mais a forma de 'raios' de luminosidade. Estes normalmente são 'semeados' a partir de pontos específicos, mas o resultado muitas vezes se estende, ao menos momentaneamente, bem além da área de semeadura. Por exemplo, um alargamento cuja máscara o limita a uma área específica fica muito, muito bobo e não natural. Os aspectos mais difíceis dos alargamentos são localizar bons pontos de 'semeadura' e cronometrar apropriadamente múltiplos alargamentos.

Em Construção

Final example I want to create...  A 'sparkle' the travels up the wizards
wand, then flares, and dissolves into a number of small sparkle flares over an
area.  Then the sequence repeats.

Redimensionamento de Animações

Problemas ao Redimensionar Animações

O maior problema ao redimensionar animações GIF é que o operador "[-resize](https://imagemagick.org/command-line-options/#resize)" foi concebido especificamente para tornar as imagens resultantes o mais próximo do ideal (após o redimensionamento) possível. Ele faz isso mesclando e gerando muitas cores adicionais na imagem para deixá-la com melhor aparência. As imagens resultantes estão longe do ideal para salvar no formato de arquivo GIF limitado. Com a tabela de cores limitada do GIF, isso resulta em pesadas Reduções de Cor nas imagens redimensionadas. Para uma única imagem GIF isso não é tão ruim, mas para animações GIF, o Pontilhamento por Correção de Erro padrão do conjunto de cores reduzido produz problemas, em 'ruído de pontilhamento' entre quadros e, por sua vez, uma má otimização de quadros para o tamanho final do arquivo. É ainda pior quando cores transparentes também estão sendo usadas, o que é uma prática comum em animações GIF típicas usadas em páginas web. A transparência também é comumente usada em técnicas de Otimização de Compressão, para animações que de outra forma não precisariam dela. O que acontece é que "[-resize](https://imagemagick.org/command-line-options/#resize)" produz pixels semitransparentes nas imagens de sobreposição. Então, quando as imagens são salvas de volta em formato GIF, esses pixels são convertidos para totalmente transparentes ou totalmente opacos, ambos produzindo grandes distorções de cor na animação resultante. Se qualquer forma de otimização for usada... de quadro, de transparência ou LZW... então os efeitos da transparência resultarão, basicamente, em uma animação GIF redimensionada de forma desastrosa. Esses são os fatos, colega! Então, você terá de conviver com isso. Mesmo que você evite usar "[-resize](https://imagemagick.org/command-line-options/#resize)", usando "[-sample](https://imagemagick.org/command-line-options/#sample)", ainda terá grandes problemas, a menos que "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)" a animação primeiro.

Técnicas de Redimensionamento de Animações

Como mostrado acima, há problemas sérios ao redimensionar animações GIF, nenhum dos quais é facilmente resolvido. A solução também depende, em geral, de qual era o tipo da imagem redimensionada em primeiro lugar, seja algo tipo desenho animado, seja uma imagem de vídeo do mundo real. Aqui estão os métodos que conheço, ou que foram contribuídos...

Evite redimensionar

Se for de todo possível, NÃO REDIMENSIONE. Você pode, por exemplo, fazer um Recorte de Tela ou Viewport da sua animação apenas para apará-la e ajustá-la ao espaço para o qual você precisa dela. Ou você pode gerar a animação GIF já no tamanho certo, de início. Nenhuma das técnicas é normalmente a melhor opção, mas, se puder, considere-a, pois ela lhe poupará muitos problemas e cabelos arrancados.

Redimensionamento direto

Como mencionado, usar diretamente "[-resize](https://imagemagick.org/command-line-options/#resize)" terá problemas, seja com o número de cores de cada quadro, seja com cores semitransparentes. Por exemplo, isto fica realmente ruim... |

  magick script_k.gif -resize 20x20 script_k_direct.gif

[IM Output]
[IM Output]
Bem, isso não funcionou muito bem, e é porque a imagem original tem algumas pesadas otimizações de quadro. Cada 'quadro' da animação não tem o mesmo tamanho, e "[-resize](https://imagemagick.org/command-line-options/#resize)" redimensionará todos e cada um dos quadros de imagem de forma completamente separada das outras imagens. Ou seja, o exemplo acima redimensionou as imagens reais dos quadros, e não a tela virtual da animação, para o tamanho dado. Na verdade, estou surpreso que a animação resultante não tenha ficado mais 'maluca' do que apenas a área em branco mostrada. Isso nos leva ao primeiro ponto sobre redimensionar animações. Primeiro, garanta que todos os quadros estejam totalmente definidos e que TODA otimização tenha sido removida. Em outras palavras, Coalesça a animação antes de tentar redimensioná-la. Por exemplo... |

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

[IM Output]
[IM Output]
O próximo problema é o das cores de transparência. Se você olhar o resultado acima, verá que as bordas da animação menor ficam horrivelmente serrilhadas ('escalonadas'). Isso é porque o GIF não consegue salvar as cores semitransparentes que o operador "[-resize](https://imagemagick.org/command-line-options/#resize)" gerou. As cores dentro do objeto animado também terão sido mescladas para produzir novas cores, mas isso normalmente não é nem de longe tão ruim quanto o serrilhamento das bordas.

Redimensionar com Achatamento, uma solução geral.

A melhor ideia ao gerar uma miniatura GIF é evitar por completo os problemas de transparência. Ou seja, Achatar a Animação, antes ou depois de redimensioná-la. Assim, você não perde a 'suavização de serrilhado' das bordas nas imagens redimensionadas. De fato, descobri que a maioria dos bons sites de animação GIF faz exatamente isso ao gerar suas miniaturas de animação GIF. É claro que a miniatura ficará então limitada ao uso sobre um fundo de cor específica, geralmente 'branco', mas às vezes 'preto', ou 'prata' (cinza de página web), embora este último seja menos comum atualmente. Por exemplo, aqui crio uma miniatura menor sobre uma cor de fundo apropriada 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 é a solução recomendada para o tratamento geral de miniaturas GIF. Qualquer outro método exige controle humano, ou uma lógica de tratamento de miniaturas GIF muito sofisticada.

Estouro da Tabela de Cores

O maior problema (como mencionei no início desta seção) é que um número enorme de cores extras é gerado na imagem, especialmente perto de linhas e das bordas de áreas de cor adjacentes. Você também obtém um halo de redimensionamento de cores semitransparentes em torno das bordas das imagens. Isso, por sua vez, aumenta o tamanho da tabela de cores necessária para uma animação simples de cores mínimas, o que, por sua vez, significa um tamanho de arquivo maior quando uma animação simples redimensionada é salva. Pior ainda, cada quadro da animação redimensionada provavelmente gera um conjunto diferente de cores, ampliando ainda mais o tamanho do arquivo da sua animação 'em miniatura'. Há também o problema de que, após a Quantização de Cores, você pode não ter mais as mesmas cores específicas da animação original (veja Quantização NÃO Preserva Cores). Ou seja, em vez de ter uma área simples de branco puro, você pode agora ter uma área de branco levemente alterado.

Redimensionar usando Sample

Para evitar gerar cores extras ao redimensionar, a maneira mais simples é usar "[-sample](https://imagemagick.org/command-line-options/#sample)" na animação, em vez de redimensioná-la. Isso preservará as cores atuais da animação e permitirá que você reotimize facilmente a animação no novo tamanho. |

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

[IM Output]
[IM Output]
No entanto, embora isso funcione, você está basicamente removendo linhas e colunas de pixels da imagem, perdendo dados de imagem e, portanto, qualidade no processo. Com imagens tipo desenho animado, isso muitas vezes deixa bordas 'pontilhadas', além de detalhes ausentes ou distorcidos. Se o seu redimensionamento for maior que 50% do tamanho original da animação, como é o caso acima, o resultado costuma ser bastante horrível, especialmente quando textura ou outro padrão de cor é usado na animação. Não é de surpreender, então, que muitas bibliotecas de animação GIF estejam repletas de animações redimensionadas por sample tão horríveis, copiadas de toda parte na rede. Muitas vezes desejo que limpem esse tipo de lixo, mas isso significa reduzir o número de GIFs em oferta, o que, por sua vez, reduz as estatísticas de marketing do número de GIFs disponíveis, algo de que o departamento de publicidade não gosta. Como consequência, animações GIF ruins são comuns.

Redimensionar usando Liquid Resize

Um método semelhante ao Sample acima é usar Liquid Rescale, também conhecido como Seam Carving. Ele também remove ou adiciona pixels inteiros das imagens envolvidas, mas tenta fazê-lo de uma forma que preserve o máximo possível da complexidade da imagem. Veja os links acima para saber como você pode usá-lo para gerar imagens redimensionadas mais agradáveis. Infelizmente, no momento, não há forma de usar isso em uma imagem animada geral, pois ele não tem uma compreensão da complexidade de uma imagem, e atualmente não conseguimos extrair o método de reescalonamento para aplicá-lo a cada quadro de uma animação de forma consistente. Espero que isso mude em algum momento no futuro.

Redimensionar e Restaurar Cores

Fazer sample de uma animação apenas resulta em remover linhas e colunas de pixels, e na possível remoção de linhas finas e outros detalhes importantes. Mas mesclar pixels usando "[-resize](https://imagemagick.org/command-line-options/#resize)" produz cores novas em número excessivo para o formato GIF. Então, a solução óbvia é fazer o "[-resize](https://imagemagick.org/command-line-options/#resize)", mas depois usar as cores da animação original para restaurar as cores da animação redimensionada, usando um colormap.

FUTURE: example with original color table restored

Isso tem a vantagem adicional de não gerar tabelas de cores locais. Os resultados, porém, podem ser melhores com o pontilhamento desligado, para evitar qualquer 'ruído de pontilhamento'. Isso é especialmente verdadeiro para imagens tipo desenho animado, que têm grandes áreas de cor suave.

FUTURE: non dithered color table restored example

Otimização de Cor Completa

Se uma miniatura horrível feita por sample não for do seu agrado, então você se depara com a perspectiva de passar por uma Otimização de Cor completa da animação GIF redimensionada. Para definir exatamente quais 'novas' cores você quer que a animação mantenha. No entanto, isso muitas vezes não é tão ruim para a maioria das animações, mas pode ser um grande esforço para animações mais complexas, como ao converter um Vídeo para Animação GIF. Ou seja, se você estiver lidando com uma animação tipo desenho animado, terá agora linhas e bordas fortemente suavizadas. Para animações que envolvem um fundo transparente, você também terá de lidar adequadamente com os pixels semitransparentes em torno da borda da sua animação, também causados pelos recursos de suavização do redimensionamento. Veja a seção sobre Transparência Booleana do GIF para os muitos métodos que você pode usar para tratar isso.

Grandes Reduções de Redimensionamento

Quando você planeja redimensionar uma animação grande para uma animação muito menor, enfrenta o problema de partes importantes da animação desaparecerem. Isso é, na verdade, um problema tanto para imagens estáticas quanto para animações. Veja Redimensionar Desenhos de Linha para quaisquer soluções conhecidas para isso. Quaisquer outras sugestões, ideias ou técnicas são muito bem-vindas.


Fundir Múltiplas Animações

Já disse isso antes, mas se torna especialmente importante ao fundir animações...

Saiba o máximo que puder sobre a animação com a qual está trabalhando!

O script "[gif2anim](../static/img/scripts/gif2anim)" é ideal para esse propósito. Seu script irmão, "[anim2gif](../static/img/scripts/anim2gif)", também é comumente usado aqui para recriar uma animação usando suas configurações originais. (Veja o uso básico do script em Informações da Lista de Animação.) Sem conhecimento de como uma animação funciona, é quase impossível fundi-las de várias maneiras. Programas podem ser desenvolvidos (o objetivo final destes exemplos) para fazer isso. Mas tais programas costumam ser muito complexos e podem produzir resultados inesperados. Por isso, você ainda deve seguir estes exemplos, pois eles lhe darão uma grande compreensão de como as animações devem ser tratadas e fundidas.

Concatenação Serial ou Temporal

Concatenar duas animações GIF de modo que uma sequência siga a outra no tempo é simples com o IM. Você basicamente apenas as lista na linha de comando e elas seguirão uma à outra. Mas talvez não seja tão fácil quanto parece. Por exemplo, após algumas buscas na web, encontrei (bem, roubei e modifiquei bastante para este exemplo) um par de animações de algumas letras sendo desenhadas. Agora, gostaria de juntar estas imagens de modo que, quando uma animação termina, a próxima começa, como se alguém estivesse escrevendo a palavra 'OK'. Aqui estão as letras, a 'sequência de animação' e os detalhes dos internos destas duas animações. | |

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

| [IM Text]

| | [IM Text]

[IM Output]
[IM Output]
Essas sequências começam com uma tela vazia e então apenas adicionam e modificam lentamente pixels nessa tela. Elas nunca removem, apagam ou tornam transparente qualquer pixel adicionado por quadros anteriores. Para os nossos propósitos, porém, não importa se fazem isso ou não, pois terá pouca influência sobre os resultados. Tampouco o número de quadros da animação terá influência sobre esta operação. O que é importante saber são os tempos do quadro, pois isso poderia gerar problemas. Em particular, observe o atraso de tempo no primeiro, ou, neste caso, no último quadro. Esta técnica é muito comum, dando ao espectador tempo de ver o resultado final antes de a animação se apagar e recomeçar. São esses atrasos e quadros que nos causarão problemas ao fazer concatenações temporais. Observe também que a animação do 'k' tem um leve atraso no meio da sequência de animação. Esse atraso representa o fim da primeira pincelada nesta animação e a segunda pincelada. Esse atraso também precisará ser preservado, o que significa que não podemos simplesmente mudar todas as sequências de tempo da animação para um valor constante. Algo que não é mostrado acima é que o primeiro quadro de ambas as animações é, na verdade, uma tela em branco. Provavelmente vamos querer descartar essa tela na segunda animação, como um desperdício inútil de tempo, embora ela deva ser mantida na primeira animação como um atraso inicial. Agora que examinamos as duas animações, vamos tentar juntá-las de modo que uma siga a outra no tempo. Concatenar animações no tempo é, na verdade, uma operação muito simples: basta concatenar as duas imagens animadas na linha de comando. Então, vamos apenas tentar isso... |

    magick script_o.gif script_k.gif   script_ok_try1.gif

[IM Output]
Bem, o resultado ficou longe do perfeito. As letras são desenhadas na sequência certa, mas umas por cima das outras! Não só isso, mas como a primeira animação do 'o' é mais estreita (40 pixels) que a segunda animação do 'k' (53 pixels), o pedacinho final da última letra 'k' fica cortado por esse tamanho de tela de enquadramento menor. A posição da segunda animação pode ser movida usando um repage relativo, como mostrado acima. Este método de reposicionamento preservará quaisquer deslocamentos existentes que possam estar presentes naquela animação, apenas movendo todos eles como um único grupo relacionado. Neste caso, quase todos os quadros têm um deslocamento existente, pois esta é uma animação altamente otimizada. Para acomodar essa posição deslocada e evitar 'cortar' a segunda animação, também precisamos aumentar o tamanho da tela de toda a animação. Alterar o tamanho da tela antes de ler a primeira animação ou quadro aumentará a área de tela em que a animação roda, e impedirá que o 'K' seja cortado. |

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

[IM Output]
O resultado é uma grande melhoria. Embora agora os atrasos entre o desenho das letras sejam claramente perceptíveis. O que queremos é um atraso bem menor para o último quadro da primeira animação do 'O'. Grande o suficiente apenas para parecer que o artista invisível está reposicionando a caneta. Para isso, fazemos uma cópia desse último quadro da primeira animação e, então, alteramos o atraso apenas desse quadro usando o operador "[-set](https://imagemagick.org/command-line-options/#set)". Depois, readicionamos esse quadro de volta à sequência de imagens, excluindo a imagem original não modificada. Além disso, como agora definimos um bom atraso entre o desenho das letras, a tela em branco inicial (que representa apenas um atraso de início) na segunda animação é agora redundante, então podemos simplesmente excluir esse quadro, sem problemas. Se esse quadro de fato contivesse parte da imagem, então talvez precisássemos ajustar seu atraso, em vez de removê-lo. |

    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]
E a nossa concatenação serial ou temporal de duas animações está completa, e todos os pequenos problemas associados a estas duas animações em particular estão corrigidos. Observe que em nenhum momento tentei alterar globalmente TODOS os quadros individuais, ou seus atrasos de tempo. Ou seja, preservei o máximo das animações originais que pude enquanto alcançava meu objetivo. Isso é importante, pois nem todas as animações usam um atraso de tempo constante entre quadros, e alterar isso pode fazer uma animação parecer muito ruim.

Concatenação Lado a Lado (sincronizada no tempo)

Suponha que você queira que ambas as animações sejam concatenadas lado a lado, mas com as duas partes da animação animando ao mesmo tempo. Isso não é tão fácil, pois você precisa concatenar (ou compor em conjunto) cada par de quadros das duas animações, para que a animação também funcione em conjunto. O verdadeiro problema para fazer isso é que a linha de comando do IM só trabalha com uma única sequência de imagens. Ela não tem o luxo de uma API onde você pode manter duas sequências de imagens separadas, para percorrê-las e concatená-las em uma terceira. Consigo pensar em três técnicas básicas para fazer essa concatenação. Antes de começarmos, porém, você deve primeiro estudar as duas animações, para verificar as sequências de tempo e outros detalhes da animação. O script "[gif2anim](../static/img/scripts/gif2anim)" é bom para isso, e o arquivo ".anim' gerado pode ser útil mais tarde. | |

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

| [IM Text]

| | [IM Text]

[left]
[right]
Se você olhar os resumos de informação, verá que as duas animações têm exatamente o mesmo número de quadros e quase exatamente a mesma sequência de tempo. É a semelhança do tempo que é importante aqui, e você pode dizer que as animações já estão 'sincronizadas no tempo'. No entanto, embora os tempos possam estar corretos, as animações têm otimização de quadros, em vez de totalmente coalescidas. Mas a altura da área de tela é a mesma, tornando prático concatenar os dois quadros lado a lado. Na verdade, esta animação foi mal 'dividida' (veja dividir animação no próximo conjunto de exemplos), de modo que a animação do 'gato' foi cortada em duas, e a original perdida. Outras modificações resultaram em uma diferença de tempo bem leve, o que só tornou a divisão mais óbvia. Este foi um problema que me foi apresentado por gmabrys em uma discussão nos Fóruns do IM, embora o problema real que ele deu fosse muito, muito pior. [left][right] Ora, os navegadores normalmente animam cada uma das imagens GIF separadas, sem qualquer sincronização. Assim, as duas animações podem ficar dessincronizadas entre si, produzindo um 'gato' que parece ter feito parte de um massacre com motosserra. Você talvez consiga ver esse efeito à direita, onde coloquei duas animações lado a lado na página do navegador, especialmente se você estiver em um servidor distante através de links lentos. Agora, vamos tentar concatená-las em uma só imagem animada, devidamente sincronizada.

Concatenar arquivos separados

A maneira mais simples é apenas coalescer as duas animações e separá-las em arquivos de imagem distintos, um quadro por imagem. As imagens separadas podem então ser concatenadas (ou os quadros modificados de outra forma) conforme apropriado. Quando pronto, os novos quadros podem então ser usados para reconstruir a animação. Isso, porém, exige que você salve muita informação extra sobre a animação, que poderia ser facilmente perdida durante esse processamento. |

  # Separate animations into coalesced frames (plus a ".anim" file)
  gif2anim -c bag_left.gif
  gif2anim -c bag_right.gif

  # Append the separated frames them together
  for i in `seq -f '%03g' 1 11`; do \
    magick bag_left_$i.gif bag_right_$i.gif +append bag_append_$i.gif; \
  done

  # Rebuild the animation (using one of the ".anim" files)
  anim2gif -c -b bag_append  bag_left.anim

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

[IM Output]
Como você pode ver, este é um processo bastante trabalhoso, gerando muitas imagens temporárias individuais e, assim, exigindo uma boa dose de limpeza ao terminar. É claro que, se você estiver depurando o exemplo acima, os arquivos temporários individuais facilitam descobrir o que está dando errado no seu processamento. Isso também mostra o poder do script "[gif2anim](../static/img/scripts/gif2anim)" e de seu inverso, o script "[anim2gif](../static/img/scripts/anim2gif)", em separar e salvar os metadados da animação e, depois, reconstruir animações GIF. Basicamente, ele permite preservar os tempos originais das animações, sem precisar codificá-los diretamente no seu script. A imagem final também ainda precisa ser reotimizada, embora, neste caso, você obtenha muito pouca otimização, já que muitas coisas estão acontecendo simultaneamente ao longo da animação, entre todos e cada um dos quadros

Composição em Camadas

Uma técnica melhor é sobrepor as animações usando uma Composição em Camadas de lista de múltiplas imagens. Isso envolve apenas aumentar um conjunto de imagens e sobrepor o outro conjunto para juntá-los. Na verdade, é isso que o operador "[-append](https://imagemagick.org/command-line-options/#append)" normal faz internamente, então não é tão diferente. Aqui, apenas digo ao IM o tamanho da tela e a preencho usando "[-coalesce](https://imagemagick.org/command-line-options/#coalesce)". Depois, sobreponho a outra animação coalescida com um deslocamento apropriado. |

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

[IM Output]
É claro que a técnica acima significa que eu precisava saber exatamente qual será o tamanho da animação final, bem como o deslocamento necessário para a animação sobreposta. Mas o processo é rápido, funciona muito bem, e um comando via script pode ler as imagens de antemão para determinar essa informação. Para tornar o método de concatenação de animação mais universal, precisamos fazer um manuseio de imagem sofisticado para determinar automaticamente o tamanho e o deslocamento finais da concatenação. Para fazer isso sem ler a animação de antemão, é preciso pular alguns obstáculos, mas uma concatenação geral de animação em um único comando é possível. Primeiro, precisamos concatenar o primeiro quadro coalescido de cada animação para criar uma tela do tamanho certo, e então ela é apagada. A primeira animação é coalescida e sobreposta na metade esquerda dessa tela, e então a segunda animação é coalescida e sobreposta com "-gravity East" para colocá-la na metade mais à direita da tela previamente preparada, evitando a necessidade de um deslocamento. |

  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]
E aí está uma técnica geral para concatenar duas animações sincronizadas no tempo.

Concatenação Dupla, Concatenar - ou Concatenar Fontes Animadas

Antes de terminar com a concatenação de animações, há mais uma técnica que gostaria de lhe mostrar. Esta técnica pode concatenar várias animações ao mesmo tempo, mas ao custo de perder toda a informação de tempo que estava presente. Muitas vezes (mas nem sempre) esses tempos não são uma grande perda. Basicamente, concatenamos todos os quadros de cada animação verticalmente em uma única imagem, e depois concatenamos ou sobrepomos toda a animação como duas imagens simples. É como colar as duas tiras de filme lado a lado para produzir uma tira de filme mais larga. |

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

[IM Output]
Isso não exigiu nenhum arquivo temporário, mas, como mencionei no início, todos os atrasos de tempo originais foram perdidos. Para este exemplo, apenas defini todos os atrasos da animação para um valor constante, produzindo um resultado razoável, embora diferente. Além disso, para reconstruir a animação, precisávamos saber a altura do quadro da animação original, para dividir corretamente (Recorte em Ladrilhos) a 'tira de filme' alargada. Embora seja possível recuperar esses tempos usando os scripts "[gif2anim](../static/img/scripts/gif2anim)", fazê-lo meio que anula o propósito de usar este método, e você poderia muito bem ter usado a primeira técnica de concatenação de animação, concatenando os quadros individuais como arquivos temporários. Como você está concatenando as animações como imagens simples, pode concatenar toda uma série de animações ao mesmo tempo (produzindo uma 'tira de filme' ainda mais larga), e é isso que torna esta técnica tão útil. Por exemplo, você pode usá-la com fontes animadas que usam todas os mesmos tempos. Embora eu tenha descoberto que, apesar de muitas fontes animadas terem o mesmo número de quadros, elas costumam ter tempos ligeiramente diferentes para cada letra, de modo a dessincronizar as letras animadas (veja Dividir uma Animação para as razões pelas quais isso é desejável). Um letreiro de neon, por outro lado, deveria ter tempos de animação sincronizados, então vou usá-lo como exemplo...

  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]

Você também poderia fazer algo um pouco mais sofisticado, ajustando os tempos e o número de laços na animação 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]

As duas primeiras linhas criam a parte 'sempre acesa' do letreiro (o primeiro quadro de cada uma das letras animadas anteriormente). Depois disso, a última letra 'quebrada' é adicionada e toda a animação é duplicada algumas vezes para produzir cerca de 16 quadros. Os tempos são definidos para completar o efeito desejado, com o primeiro e o último quadro sendo exibidos por um longo período, enquanto o restante dos quadros passa voando bem rápido ( "-delay 10" ). Na verdade, esta animação GIF otimiza para um tamanho bem menor do que você provavelmente pensaria, para o número de quadros envolvidos. Basicamente, o otimizador GIF do IM descobriu que só precisava sobrepor de novo a animação do 'O' a cada segundo quadro, e usou uma supressão 'Previous' para apenas restaurar o 'O' aceso anterior. A animação fica, assim, apenas cerca de 50% maior que a imagem 'hello' básica, piscante e não otimizada. Confira você mesmo. Você consegue melhorar a animação de neon? Torná-la mais realista? É uma pena que animações GIF não tenham som.

Dividir uma Animação

Agora que temos a animação novamente unida, vamos tentar dividi-la corretamente para uso em servidores web, de modo que as partes individuais possam animar separadamente, sem interferir umas nas outras. Isso é, na verdade, razoavelmente difícil, e não vou tentar automatizar completamente o processo. Há, porém, ferramentas na WWW que podem fazer isso. Antes de tudo, precisamos estudar a animação para descobrir quais partes da animação mudam ao longo de todo o período. Para isso, precisamos encontrar as diferenças de um quadro para o próximo, somá-las todas em um mapa que mostre as áreas que estão sendo animadas, em contraste com as que permanecem completamente estáticas. Isto é complicado. Basicamente, uma Composição Alfa de Múltiplas Imagens é usada para encontrar uma imagem de '[Difference](compose.html#difference)' entre cada quadro da animação. Essas imagens de diferença em tons de cinza são somadas, e então os canais são separados e também somados. Um limiar final torna qualquer mudança diferente de zero entre quaisquer quadros da animação em branco puro. O resultado é uma imagem preta com branco em qualquer lugar onde a imagem mudou, destacando as áreas de mudança.

  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]

Agora, podemos ver que esta animação poderia ser dividida em pelo menos três áreas: uma área de 'gato' no topo, um pequeno 'urso' à esquerda e uma 'asa' batendo à direita. Tudo com cortes ortogonais simples (verticais ou horizontais). Então, vamos apenas fazer isso, com alguns simples Recortes de Viewport da Animação. |

  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 três imagens podem ser exibidas pelo navegador em conjunto e não ter aquele aspecto de 'Massacre da Serra Elétrica', pois em nenhum momento uma subanimação cruza os limites de outra. Agora, tecnicamente, você pode fazer mais alguns cortes para separar as áreas que não são animadas das áreas animadas, dividindo esta animação em cerca de seis áreas ou mais, embora você não ganhe muito com otimização ao fazer isso. Tudo o que isso realmente faria seria complicar a sua página web e criar mais arquivos para o usuário baixar. Agora, ao contrário da animação maior, essas áreas menores animarão de forma bem independente umas das outras. Podemos até mesmo alterar os tempos dessas simples subanimações sem afetar negativamente o resultado, de modo a dessincronizá-las completamente das outras subanimações. O resultado é uma imagem animada mais agradável e menos repetitiva (veja abaixo). Se você estudar o 'urso saltitante' e a 'asa batendo', descobrirá que eles formam um simples ciclo de dois quadros, que simplesmente se repete várias vezes, para coincidir com o tempo do gato acenando. Podemos, assim, descartar as repetições extras para simplificar essas animações. Além disso, os dois primeiros quadros do 'gato' também são exatamente iguais. No entanto, ao contrário do 'urso' e da 'asa', você não pode simplesmente remover um deles, pois cada quadro contém atrasos de tempo para permitir que o 'urso' e a 'asa' animem sem o gato estar presente. Para remover corretamente esses quadros duplicados, você precisa usar o método '[RemoveDups](anim_opt.html#removeDups)' de "[-layer](https://imagemagick.org/command-line-options/#layers)" para localizar e fundir os tempos de tais quadros duplicados em uma animação coalescida. E aqui estão as otimizações finais, das três animações separadas, com as mudanças de tempo para melhorar a dessincronização geral das subanimações. Também exibi todas as três animações lado a lado na página, exatamente como deveriam ser exibidas. |

  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 resumo final: as duas imagens originais (mal divididas) totalizavam [IM Text] bytes, o que é aproximadamente o mesmo que a versão concatenada. Após dividir corretamente a animação, o que permite uma boa otimização das subanimações, obtemos um total de [IM Text] bytes em três imagens. Uma economia bem boa.

Divisão de Quadros por Mudança Distante

Em Construção

Exemplo de dividir as atualizações de quadro de 'dois objetos em mudança que estão distantes um do outro', sem envolver transparência (fundo fixo), mas preservando a sincronização de tempo entre as partes. Depois, repetir com um fundo de transparência (precisando de 'OptimizePlus' para gerar os pixels 'apagados'. Veja Dividir Ações de Quadro para o exemplo geral.

Fundir Animações Temporalmente Disjuntas

Antes que duas animações quaisquer possam ser fundidas para rodar de forma síncrona, você precisa fazer todas as animações usarem o mesmo número de quadros e o mesmo conjunto de atrasos de tempo. O quão difícil é a fusão realmente depende de quão disjuntos são os tempos da animação. Se os atrasos de tempo forem basicamente constantes, você pode simplesmente ignorá-los e corrigir os tempos depois. Um exemplo em que o tempo pôde ser ignorado ao fundir uma animação de 2 quadros com uma de 6 quadros foi dado em uma Discussão no Fórum do IM. Além disso, se o tempo total de ciclo for muito diferente, talvez você precise ajustar as coisas para que uma animação entre em laço 2 ou 3 vezes, de modo a preencher o tempo de ciclo da outra animação. Basicamente, é o tempo que importa.

Provavelmente algo como... * + Descobrir e ajustar as animações para um tempo total de ciclo de laço comum * + Coalescer ambas as animações para remover quaisquer otimizações de quadro. * * Converter os atrasos de tempo de quadro em tempo desde o início da animação. * * Duplicar quadros conforme apropriado para sincronizar no tempo. * * Converter o tempo desde o início de volta em atrasos de tempo de quadro. * + Sobrepor os quadros coalescidos e sincronizados no tempo conforme desejado. * + Fundir de forma ótima e remover quaisquer quadros de 'atraso zero'. * + Reotimizar a nova animação.

As partes marcadas com '*' poderiam ser transformadas em um único método novo de "[-layer](https://imagemagick.org/command-line-options/#layers)" para sincronizar no tempo as duas animações com durações de tempo total de ciclo semelhantes.

Em Construção

Example, time disjoint, but same cycle time...

For example suppose you have two animations of three frame with time delays of
    10  10  10
    5    5  20

Both animations are 30 time units long already so that is not a problem.

Now magick the above to the time index when each frame should appear...
and show the overall time line at which frames appear...
   0        10    20   |__ NOTE that both animations
   0   5    10         |   end or loop at 30

From this you can see that you need to insert some extra frames to make them
match.  The first frame of the first animation needs to be repeated at time
index 5

0->5  10  20
0  5  10

And the last frame of the second animation also needs to be duplicated at
time index 20

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

The arrow '->' in the above means the same frame is just repeated (duplicated)
into the next time index. They are actually the same image.

Now that the timings of the frames in both animations are the same, you can
simply merge (composite) the frames together, to get final animation that is
4 frames long.

The four frame will thus have time delays of
5  5  10  10
which still add up to 30 time units (overall time per loop cycle)

Current state of development....

While IM can help gather time delay information (try the '-t' option for
"gif2anim") and build the animation. IM can't perform the time synchronization
needed for two separate coalesced animations.  This may become a special
built-in option.

That is, you will need figure out and double up appropriate coalesced
animation frames so as to change two time-disjoint animations into two
time-synchronized animations.

Once you have the animations time synchronized, you can then simply use the
new "-layers Composite" method, to overlay or merge the two time-synchronized
animations  together very easily.

All the above however assumes the total loop time of the two animations
are at least roughly equal, or not a major concern.


**Simplified Solution**

A simplified limited solution has been [Discussed on IM Forums](https://magick.imagemagick.org/viewtopic.php?p=50325), for use with fast changing animations (similes).

The solution takes each animation and expand it so that the animation has
a fixed frame rate.  That is, all frames are duplicated so that each frame is
shown for a conatant 6 centi-seconds each.  As such one frame with a 22cs
delay may be replaced by 4 x 6cs frames (24cs total).

After this the animations are further modified so that short animations are
looped multiple times so that the two animations are finally of equal length.
That is, the two animations are made the same overall length in terms of both
time, and number of frames.

Once both animations has the same frame-rate and the same length, [Layer Composition](#composite) can be used to merge/overlay the two
animations, in the right position.

The result can then be optimized using [Remove Duplicate Frames](anim_opt.html#removedups) to remove any extra unwanted frames (with
appropriate timing adjustments and other [Optimizations](anim_opt.html#intro) applied before saving.

This method of having all your component animations in a fixed frame length
form is especially well suited to animation libraries.


-----
Other example to create....
  * Overlay two moving equal time animations into a single animation
    (dancing butterflies, circling atoms, or birds?)
    This should be a straight layers composition.

  * Overlaying a moving animation on a fix background.
    (displace animation linearly with time)

  * Overlay two animations with different numbers of frames but constant time
    delays (see [IM Forum Discussion](https://magick.imagemagick.org/viewtopic.php?t=12573)).

  * Oveylay two time disjoint animations (as outlined above)

  * Overlay a simple animated figure, on an animated background.
    (full animation merge)