⚠️ Ceci est un site de traduction non officiel, sans lien avec ImageMagick Studio LLC. Pour des informations officielles, consultez la page originale (https://usage.imagemagick.org/anim_mods/index.html).

Exemples ImageMagick -- Modifications d'animations

Exemples ImageMagick : préface et index
Modifications simples des animations

Cette page contient des exemples pratiques de manipulation d'animations GIF. Il est fortement recommandé de lire et de comprendre les bases des animations et, au minimum, la manière générale de gérer l'optimisation des animations GIF avant d'essayer de comprendre ces exemples.


Modifications simples des animations

D'abord un point important

N'enregistrez PAS directement au format GIF les animations intermédiaires dont le traitement n'est pas terminé, en particulier les images sur lesquelles vous n'avez encore effectué ni gestion de la semi-transparence ni optimisation des couleurs. Si vous commettiez la grosse erreur d'enregistrer au format GIF, vous ne feriez que dégrader l'animation résultante, car IM aurait alors effectué une quantification des couleurs automatique pour réduire le nombre de couleurs présentes et faire tenir les images dans les limites du format GIF. Et ce n'est pas tout : il traiterait chaque image indépendamment de toutes les autres, produisant des choix de couleurs et des motifs de tramage différents. Cela rend d'autant plus difficile tout traitement ultérieur, en particulier toute optimisation des images. C'est particulièrement important pour les animations GIF redimensionnées, ou pour celles auxquelles vous avez ajouté une surimpression ou une sous-couche multicolore, car cela peut ajouter beaucoup de couleurs supplémentaires. Vous pouvez utiliser le format interne d'IM, le MIFF, comme format de fichier temporaire si vous souhaitez travailler une animation par étapes, ou utiliser des images individuelles au format PNG pour chacune des images à éditer. Ne faites simplement pas l'enregistrement final en GIF tant que vous n'êtes pas certain de ne pas avoir de problèmes de couleurs. Je répète...

N'utilisez pas le GIF comme format de fichier intermédiaire ; utilisez le MIFF ou des images PNG.

Depuis la version 6.2.6 d'IM, vous pouvez « [-annotate](https://imagemagick.org/command-line-options/#annotate) » une animation, de la même façon que celle détaillée dans Annoter par-dessus les images, simplement en le faisant. Par exemple, ici nous annotons l'animation previous dispose créée dans Les bases des animations. |

  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]

Cela fonctionne parce que « [-annotate](https://imagemagick.org/command-line-options/#annotate) » positionne le texte par rapport au canevas virtuel d'une image, et non par rapport aux données réelles de l'image. Ainsi, la position du texte sur chaque image est correcte pour une image animée. Avant la version 6.2.6, cependant, « [-annotate](https://imagemagick.org/command-line-options/#annotate) », comme beaucoup d'autres opérateurs d'image, positionnait les informations et les surimpressions par rapport à l'image réelle, et ignorait tout décalage de page ou de canevas virtuel que pouvait avoir une sous-image. Un mot d'avertissement : dessiner ainsi sur une animation sans d'abord la fusionner (coalesce) peut provoquer des effets inhabituels, en raison du schéma d'optimisation existant de l'animation (voir la série d'exemples suivante). C'est pourquoi (et comme vous le verrez), il est recommandé de supprimer d'abord toute optimisation d'image et de transparence existante en la fusionnant (coalesce).

Dessin - modifier une animation fusionnée (coalesced)

Or, si « [-annotate](https://imagemagick.org/command-line-options/#annotate) » place le texte par rapport au canevas virtuel de chaque image, beaucoup d'autres opérations d'image ne le font pas. Cela inclut toutes les opérations « [-draw](https://imagemagick.org/command-line-options/#draw) », qui ne dessinent que par rapport à l'image réelle et ignorent complètement tout décalage qu'elle pourrait avoir sur un canevas plus grand. Par exemple, ici nous dessinons un joli cercle vert près du coin supérieur gauche de l'animation previous dispose. |

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

[IM Output]

[IM Output]

Comme vous pouvez le voir, « [-draw](https://imagemagick.org/command-line-options/#draw) » a dessiné le cercle par rapport à l'« image réelle », plutôt qu'au grand canevas virtuel (de page) dont l'image fait partie. Le résultat est, comme c'est typique dans ce genre de situation... le chaos. La solution simple consiste à d'abord fusionner (coalesce) l'animation avant de dessiner, puis à réoptimiser l'animation GIF ensuite. Voir Optimiser les animations pour les détails. |

  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]

Remarquez comment l'optimiseur d'animation d'IM a en réalité décidé de simplement ne pas réécrire la partie qui a été dessinée. C'est en fait plus optimal que s'il avait dessiné sur les sous-images elles-mêmes. Cette méthode vous permet de superposer n'importe quel type d'annotation, mention de copyright ou filigrane de votre choix. Bien sûr, vous devrez peut-être utiliser la technique spéciale de composition en couches pour superposer réellement une image sur chaque image d'une animation. Si vous devenez vraiment doué, vous pouvez même aller jusqu'à réaliser une fusion d'animations pour superposer une mention de copyright animée sur votre animation. | _Bien que cette technique de « coalesce-optimize » (fusionner puis optimiser) fonctionne avec la plupart des opérations impliquant des animations, en particulier avec l'optimiseur d'IM, certaines opérations apportent des changements si radicaux aux images, comme des modifications de couleurs importantes, des ombrages ou de la semi-transparence, que l'animation résultante s'optimise très mal.

Par exemple, à peu près toute opération « [-resize](https://imagemagick.org/command-line-options/#resize) » est susceptible de produire une animation qui s'optimisera très mal ensuite en raison de changements de couleurs importants. Voir Redimensionner les animations ci-dessous pour des solutions à cela.

_
---|---

Image par image - modifier une image à la fois

En utilisant les opérateurs de liste ou de séquence d'images d'IM, vous pouvez modifier chaque image de l'animation séparément. L'astuce consiste à extraire chaque image entre parenthèses, à la modifier, puis à remplacer l'image d'origine par la version modifiée. Par exemple, ici nous ajoutons du texte comme filigrane de copyright dans l'animation, sous forme d'animation elle-même, ce qui rend son retrait encore plus difficile. Pour ne pas détruire complètement l'animation, j'ai également utilisé des couleurs semi-transparentes. |

  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]

Remarquez l'utilisation des parenthèses pour limiter l'effet de l'opération « [-annotate](https://imagemagick.org/command-line-options/#annotate) » à un simple « clone » d'une seule image de l'animation. L'image modifiée est ensuite renvoyée à sa position correcte dans la séquence d'images à l'aide des opérateurs Swap et Delete. L'usage d'un seul nombre dans l'opérateur « [-swap](https://imagemagick.org/command-line-options/#swap) » a été ajouté dans IM v6.3.4-3. Auparavant, il fallait spécifier « -swap 3 » sous la forme « -swap -1,3 » pour que cela fonctionne correctement.
Cette technique de modification des images individuelles sera probablement l'une des techniques les plus importantes que vous rencontrerez pour manipuler les animations d'images. Vous remarquerez aussi que j'ai en fait ajouté le même texte à la première et à la deuxième image. La première image de l'animation ci-dessus est une image intermédiaire à délai nul, qui sert à définir l'arrière-plan du reste de cette animation. Autrement dit, elle passe si vite qu'elle n'est généralement pas visible pour les utilisateurs, et elle n'est pas censée l'être. Ainsi, les deux premières images réelles de l'animation ci-dessus devraient être considérées comme une seule image visible, plutôt que comme deux images distinctes. L'image ayant un délai non nul est la dernière image d'une séquence d'affichage. De même, pour d'autres animations à défilement rapide, vous devrez peut-être modifier plusieurs images pour que votre changement reste visible pendant une durée appréciable. Ce n'est pas un problème pour une annotation statique dessinée sur toutes les images (voir l'exemple précédent Annotation ci-dessus). Cela nous amène à un point important à propos des animations GIF.

Étudiez une animation avant d'essayer de la modifier.
Cela peut faire une GRANDE différence sur le résultat final.

Rognage - limiter la zone de l'animation

IM s'est efforcé de faire fonctionner l'opération d'image « [-crop](https://imagemagick.org/command-line-options/#crop) » correctement par rapport au canevas virtuel d'une image plutôt qu'à l'image réelle (depuis la version 6.1.1 d'IM). Cela permet à son tour de faire des choses qui n'étaient pas directement possibles auparavant. Par exemple, rogner les images d'une animation GIF tout en la faisant fonctionner comme prévu pour toutes les animations. |

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

[IM Output]

[IM Output]
Comme vous pouvez le voir, le rognage a fonctionné, tout comme pour le rognage d'une image unique, en préservant le décalage et la taille de page appropriés, de sorte que les données de l'image restent correctement positionnées, même si la zone concernée a été réduite. Comme vous pouvez le constater, cela n'a pas modifié la taille globale du canevas virtuel ! | N'utilisezpas « [+repage](https://imagemagick.org/command-line-options/#repage) » pour supprimer les décalages de rognage d'une animation GIF optimisée par image. Cela supprimerait aussi les décalages d'image nécessaires qui positionnent les sous-images sur le canevas virtuel, et dont les images ultérieures peuvent dépendre pour s'animer correctement.
---|---
L'opération « [-crop](https://imagemagick.org/command-line-options/#crop) » ci-dessus a toutefois produit un message d'avertissement...

[IM Text]

C'est parce que le rognage de l'une des images de l'animation a manqué la sous-image de surimpression utilisée pour cette image. Autrement dit, une image n'a pas mis à jour la zone qui a été rognée de l'animation. En conséquence, cette image ne contient plus aucune image réelle ! Pour compenser, IM ne se contente pas de produire un message d'avertissement, mais génère une « image manquée » spéciale comme espace réservé dans l'animation, afin de maintenir la cohérence et de préserver les méthodes de « delay » ou « disposal » attachées à cette image. Vous pouvez laisser cet espace réservé ou le corriger comme bon vous semble. Dans ce cas, l'« image manquée » est nécessaire pour que l'animation se déroule comme prévu. Cependant, si plusieurs images manquées consécutives sont générées, vous pouvez probablement les fusionner en une seule image manquée à l'aide de la méthode « [RemoveDups](anim_opt.html#removedups) » de « [-layers](https://imagemagick.org/command-line-options/#layers) ». La prudence et l'étude de l'animation restent néanmoins recommandées. (Voir Découper une animation ci-dessous pour un exemple plus détaillé de ceci.)

Rogner aussi le canevas - rognage par fenêtre d'affichage de l'animation

Tout comme un rognage normal préserve le canevas virtuel des images d'origine, un rognage d'animation le fait aussi. Ce n'est probablement pas l'intention dans ce cas. C'est pourquoi, dans la version 6.2.4-5 d'IM, un indicateur spécial « ! » a été ajouté à l'argument de « [-crop](https://imagemagick.org/command-line-options/#crop) ». Cet indicateur fait en sorte que le rognage ne rogne pas seulement les images individuelles, mais ajuste aussi les informations de page ou de canevas de l'image à cette même zone. C'est ce qu'on appelle un « rognage par fenêtre d'affichage » (viewport crop), car le résultat sera comme si vous regardiez l'image à travers une « fenêtre » ou une « fenêtre d'affichage » de la taille et de la position de l'argument de rognage. Non seulement la taille du canevas virtuel est fixée à la taille de la zone de rognage, mais le décalage de chaque image de l'animation est ajusté pour maintenir la cohérence. (Voir Rognage par fenêtre d'affichage avec ajustement du canevas/de la page). Par exemple, répétons le rognage précédent, mais en rognant aussi les informations de canevas à l'aide de l'indicateur « ! »... |

  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]
| Le caractère « ! » a une signification particulière pour certains shells UNIX, comme « csh », et doit être échappé par une barre oblique inverse, même lorsqu'il est placé entre guillemets. IM ignore les barres obliques inverses dans les arguments de géométrie, donc il n'est jamais gênant de toujours l'échapper.
---|---
Comme vous pouvez le voir, le résultat correspond davantage à ce que vous vouliez probablement vraiment obtenir en rognant une image animée. Notez que j'ai inclus un réglage « [-quiet](https://imagemagick.org/command-line-options/#quiet) » pour demander à IM de ne pas afficher le message d'avertissement concernant l'image manquée que nous avons générée lors de la tentative de rognage précédente. C'est recommandé chaque fois que l'on rogne des animations, car l'avertissement ne s'applique pas vraiment. Notez qu'un rognage par fenêtre d'affichage vous permet aussi d'agrandir la zone de canevas, voire de tout repositionner à l'intérieur du canevas. C'est toutefois dangereux, car toute image qui tombe partiellement ou entièrement en dehors de la zone de rognage sera réduite pour ne montrer que la partie de l'image qui apparaît dans cette zone. Un dernier mot d'avertissement. Lorsqu'on utilise un « rognage par fenêtre d'affichage », les images sont déplacées dans le sens négatif du décalage indiqué pour la « fenêtre d'affichage ». Cela peut sembler illogique, à moins de se rappeler que le décalage de l'opérateur de rognage est la position de la fenêtre d'affichage, et non un repositionnement direct des images elles-mêmes.

Rognage aux limites - correction automatique de la taille du canevas

Comme pour les opérations précédentes, rogner une animation peut être délicat. Si l'animation est constituée d'une simple animation à image effacée, alors vous pouvez la rogner simplement en déterminant les limites maximales de toutes les images individuelles de l'animation. Depuis IM v6.3.4-8, vous pouvez le faire très facilement à l'aide d'une méthode de couche « TrimBounds ».

  magick anim_bgnd.gif -layers TrimBounds anim_trim_bounds.gif

[IM Output] [IM Output]

Pour les utilisateurs d'IM antérieurs à cette version, vous pouvez toujours faire la même chose, mais uniquement en deux étapes (ce qui effectue aussi d'autres traitements indésirables). Pour cela, vous utiliseriez un fusionnement de couches (merge) pour fusionner toutes les images d'une animation en une seule couche, puis vous demanderiez à IM de rapporter la taille et le décalage de cette couche...

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

[IM Text]

Maintenant que vous connaissez les limites de toutes les images, il vous suffit d'appliquer un rognage par fenêtre d'affichage à l'ensemble de l'animation selon cette taille.

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

[IM Output] [IM Output]

Si vous voulez aussi retirer un fond statique d'une animation, votre meilleure option est de supprimer la première image d'une animation optimisée par image avant d'utiliser l'étape de fusionnement de couches (merge). Vous pouvez ensuite utiliser les limites renvoyées pour le rognage par fenêtre d'affichage sur l'animation d'origine.

Repositionner les images

Une opération similaire et connexe est l'opérateur de « repage relatif ». Il ajoute le décalage indiqué à toutes les couches de sous-images individuelles de l'animation, ce qui vous permet d'ajuster leur position par rapport à l'ensemble du canevas. Pour rendre une opération « [-repage](https://imagemagick.org/command-line-options/#repage) » relative, vous ajoutez également un indicateur « ! » à son argument. Par exemple, ici nous décalons les deuxième et suivantes images d'une animation de 30 pixels vers le bas et la droite, en ramenant la première image « d'arrière-plan » à sa position normale « +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]


| L'animation ci-dessus échouera (elle n'affichera que les deux premières images) sous Windows Internet Explorer version 8. Cela se produit chaque fois qu'une image tente de dessiner une image au-delà des limites du canevas de l'animation.
---|---
Remarquez qu'aucune des images n'a été « rognée » ni réduite. Seules leurs positions ont été modifiées, par rapport à l'image d'arrière-plan d'origine, même si l'image a été déplacée « hors du canevas ». Si vous le souhaitez, vous pouvez aussi étendre le canevas pour l'adapter à ces nouvelles limites, soit en ajustant directement la taille du canevas... |

  magick repage_offset.gif -repage 130x130  repage_canvas.gif

[IM Output]
En utilisant la méthode de couche de rognage aux limites, vous pouvez étendre automatiquement les limites de l'animation juste assez pour inclure les images qui se retrouvaient placées « hors limites »... |

  magick repage_offset.gif -layers TrimBounds repage_bounds.gif

[IM Output]
| _Utiliser « [-repage](https://imagemagick.org/command-line-options/#repage) » pour déplacer des images vers la gauche ou vers le haut, en particulier avec un petit canevas, est susceptible d'échouer pour les animations GIF. Ce format ne peut fondamentalement pas utiliser de décalage d'image négatif.

Pour cela, il vaut peut-être mieux appliquer aussi un « rognage par fenêtre d'affichage », ou utiliser le « rognage aux limites » pour décaler tous les décalages vers un canevas positif plus grand. L'une ou l'autre méthode garantira un décalage positif pour toutes les images.

Les formats PNG et MNG peuvent gérer les décalages négatifs, mais beaucoup de navigateurs web et d'autres programmes peuvent ne pas comprendre de tels décalages, produisant des effets étranges. Une version du navigateur web « Firefox », par exemple, produit des images extrêmement grandes lorsqu'elle tente d'afficher un PNG avec un décalage négatif._
---|---

Inverser les animations - faire tourner les animations à l'envers, ou en cycle

Depuis IM v6.3.3, l'opérateur de séquence d'images « [-reverse](https://imagemagick.org/command-line-options/#reverse) » a été ajouté (voir Opérateur Reverse pour plus de détails). Cela vous permet d'inverser très simplement l'ordre d'une séquence d'animation fusionnée. Par exemple, ici je fais en sorte qu'une animation de « k tracé à la main » se dé-trace ! |

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

[IM Output]
J'ai dû ré-ajouter l'option « [-loop](https://imagemagick.org/command-line-options/#loop) » à ce qui précède, car elle doit être attachée à la première image, qui est maintenant la dernière image ! Le résultat pourrait aussi bénéficier de quelques ajustements de timing, mais comme vous pouvez le voir, il « dé-trace » désormais la lettre ! Veillez à « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) » la séquence d'images avant de l'inverser, car toute optimisation d'image présente dépend de l'ordre des images. Mieux vaut supprimer ces optimisations d'abord.

Cycles de patrouille - osciller d'un bout à l'autre

Une technique similaire consiste à ajouter à la fin de l'animation les images dans l'ordre inverse, de sorte que l'animation résultante oscille entre la première et la dernière image de l'animation d'origine. C'est un peu comme un garde effectuant une patrouille entre deux points, et on parle de « cycle de patrouille ». Ici, j'utilise l'opérateur de duplication d'images (ajouté à IM v6.6.8-7) pour générer les images supplémentaires (inversées). |

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

[IM Output]
Remarquez que je n'ai pas simplement copié toutes les images de l'animation, mais que j'ai omis de copier la toute première et la toute dernière image de la séquence d'origine. Si j'avais copié toutes les images, la première et la dernière apparaîtraient pendant le double de la durée attendue et rendraient le fichier d'animation plus gros que nécessaire. Cela dit, vous devriez à nouveau vous méfier des images intermédiaires à délai nul au début et à la fin de l'animation, car elles peuvent provoquer des problèmes inattendus. Fondamentalement, ne faites pas cela sans d'abord étudier l'animation, sinon vous cherchez les ennuis. De plus, pour permettre une meilleure optimisation du résultat, vous devrez peut-être même ajouter quelques images intermédiaires à délai nul supplémentaires entre les cycles avant et arrière, afin d'améliorer l'optimisation. Ces images supplémentaires n'étaient probablement pas prévues dans l'optimisation de l'animation d'origine, car l'ensemble de l'animation se réinitialise normalement lorsqu'elle boucle. Voir Découper les mises à jour d'images pour plus de détails sur la façon dont ces images supplémentaires aident à optimiser et à améliorer l'animation. Voici une ancienne méthode utilisant l'opérateur de clonage pour générer des images dupliquées. |

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

[IM Output]

Morphing de couleur - transition animée entre deux images

L'opérateur « [-morph](https://imagemagick.org/command-line-options/#morph) » est un opérateur particulièrement intéressant. Il prend une liste d'images et insère des images supplémentaires entre elles, de manière à réaliser un changement de couleur en douceur d'une image à la suivante. Cet opérateur n'est cependant pas un véritable « morph », car il ne modifie que la couleur des pixels, créant une séquence d'images fondues. Un véritable « morph » à la manière du cinéma implique aussi une distorsion de l'image pour transformer le contour de l'objet d'une image en celui des objets de l'autre image. Par exemple, ici je crée un cycle de patrouille en utilisant un morphing de couleur pour générer les images supplémentaires entre l'image de la rose et sa forme retournée. |

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

[IM Output]
Ce n'est pas particulièrement réussi, car toutes les images ont le même délai. Résultat : l'animation ne semble jamais « se reposer » ni marquer de pause entre les deux extrémités du cycle. Une meilleure solution serait de marquer une pause sur l'original et sa forme « retournée ». Cela nécessite toutefois d'ajuster les délais des images d'origine pour qu'ils diffèrent de ceux des images du 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]
Comme vous pouvez le voir, les délais de timing peuvent devenir très importants pour générer de bonnes animations, en permettant à l'animation de « se reposer » aux bons endroits. Depuis IM v6.6.9, vous pouvez régler le délai à l'aide des échappements de pourcentage FX, calculés en fonction de l'indice de l'image. Ici, l'expression FX dit d'utiliser un délai de 10 si l'indice de l'image n'est ni le premier (t=0) ni le dernier (t=n-1), et sinon d'utiliser une valeur plus grande. |

  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]
Pour toute une gamme de méthodes différentes de « morphing » ou de « transition » d'une image à une autre, voir les scripts shell ImageMagick « [transitions](http://www.fmwconcepts.com/imagemagick/transitions/) » et « [fxtransitions](http://www.fmwconcepts.com/imagemagick/fxtransitions/) » de Fred Weinhaus. La page d'exemples inclut l'algorithme de base que le script utilise pour générer l'animation.

Morphing de redimensionnement - variation de taille animée

L'opérateur de morphing de couleur ne fait pas seulement une fusion de couleurs entre deux images, il effectue aussi un redimensionnement d'image en même temps. Par exemple, ici j'utilise « [-morph](https://imagemagick.org/command-line-options/#morph) » sur deux images de tailles différentes, et même de rapports d'aspect différents. |

  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]
Seule la première ligne effectue le morphing de redimensionnement. Si vous regardiez les images réelles, chaque image aurait une taille différente ! Les deux lignes suivantes « complètent » les images pour qu'elles aient toutes la même taille, en remplissant de noir les parties inutilisées. Concrètement, l'opération est conçue de sorte que l'ordre des images n'ait pas d'importance. Le reste ne fait que mettre en place un cycle de patrouille et les délais de timing associés. Le « redimensionnement » s'effectue uniquement depuis le coin supérieur gauche. Au moment de la rédaction, l'opérateur de morphing de couleur ne comprend ni les décalages de couche ni aucun autre morphing spatial (morphing avec distorsion). Ainsi, si vous voulez que le redimensionnement soit centré, vous devrez peut-être recourir aux techniques bien plus complexes présentées dans les sections ultérieures. Voici un exemple similaire, cette fois-ci en redimensionnant l'image avec une version plus petite de la même image (rapport d'aspect préservé)... |

  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]
Remarquez que les images « intermédiaires » sont plus floues qu'elles ne devraient probablement l'être. C'est parce que l'image plus grande n'est pas seulement redimensionnée en plus petit, mais qu'elle est aussi fondue en couleur avec l'image plus petite qui a été redimensionnée en plus grand.

Balayage (wipe) - créer un balayage d'une image vers une autre

C'est en fait très facile à réaliser. Il suffit de superposer des « lamelles » de la nouvelle image. Elles sont générées directement à l'aide d'un simple rognage en tuiles. Par exemple, ici nous « balayons » d'une image vers sa version retournée, et, pour le plaisir, nous balayons à nouveau en sens inverse. |

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

[IM Output]
Voici une version de GeeMack, sur les forums IM, qui implémente des balayages depuis les quatre directions... |

  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]

Distorsions animées - déformer plusieurs images en fonction de leur indice

Beaucoup d'opérateurs peuvent utiliser des échappements de pourcentage dans leurs arguments. Cela signifie que vous pouvez en fait modifier l'opérateur pour qu'il se comporte légèrement différemment pour chaque image traitée. La méthode consiste d'abord à dupliquer des images pour créer 30 copies identiques (ou autant que vous voulez) de l'image de la rose. Vous modifiez ensuite chaque image différemment à l'aide des échappements de pourcentage FX pour calculer des valeurs de distorsion, à partir de l'indice de l'image « %[fx:t] » et du nombre d'images dans la liste « %[fx:n] ». Par exemple, ici je translate l'image d'une quantité calculée. |

  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]
Et ici je fais pivoter l'image en fonction de l'indice, mais je génère une pause plus longue si l'indice de l'image est 0 (la première image). |

  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]
Remarquez que l'indice de l'image (« t ») prend une valeur de « 0 » à « n-1 », de sorte que la formule « %[fx:t/n] » prend une valeur de « 0.0 » à une valeur juste inférieure à « 1.0 ». C'est parfait pour une animation répétitive ou cyclique comme ci-dessus, mais ce n'est peut-être pas très adapté pour générer des transitions d'une image vers une nouvelle image. Dans ce cas, vous voulez que l'image finale ait un multiplicateur de « 1.0 » pour la dernière image ; utilisez la formule « %[fx:t/(n-1)] ». Ceci n'est qu'un aperçu de ce qui peut désormais se faire facilement en utilisant les indices d'image dans les calculs « %[fx:...] ». Imaginez ce qui est possible avec des distorsions plus complexes. Sans l'utilisation des calculs d'indice d'image, ce qui précède aurait nécessité une boucle shell externe pour générer chaque image individuellement, et une étape distincte pour rassembler les images afin de former l'animation finale. Des exemples de tels scripts shell à boucle sont donnés dans Animations simples d'images déformées, car ces opérateurs ne permettent pas l'utilisation des échappements de pourcentage dans leurs arguments. | Avant IM v6.6.9-0, leséchappements de pourcentage et les échappements de pourcentage FX impliquant des indices d'image, comme « %p », « %n », « %[fx:t] » et « %[fx:n] », étaient défaillants. Typiquement, ils ne renvoyaient que des valeurs inutiles, soit « 0 » soit « 1 », et non l'indice réel ni le nombre d'images de la séquence d'images en cours.
---|---

Ajouter un libellé - ajouter un libellé à toute l'animation

Comme toujours, il existe plusieurs façons d'ajouter réellement un libellé à une image. Par exemple, pour les animations qui ont un canevas d'arrière-plan initial, ou qui ne font que superposer de nouvelles couleurs sur les images précédentes, vous pouvez simplement ajouter le libellé à la première image. Les autres images ne le supprimeront pas. Ici, nous ajoutons simplement un peu d'espace supplémentaire avec « [-splice](https://imagemagick.org/command-line-options/#splice) », et nous y « [-annotate](https://imagemagick.org/command-line-options/#annotate) » un texte. |

  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]
Cela ne fonctionne toutefois que pour certaines animations. Cela ne fonctionnerait pas pour une animation à image effacée courante, qui efface ou remplace tous les pixels après l'affichage de chaque image. Pour une méthode plus générale qui fonctionne pour toutes les animations, nous devons d'abord « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) » l'animation en une animation fusionnée non optimisée. Nous pouvons alors ajouter le libellé à chacune des images fusionnées de l'animation, avant de la réoptimiser. |

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

[IM Output]
Plutôt que d'utiliser « [-annotate](https://imagemagick.org/command-line-options/#annotate) » pour dessiner du texte dans l'espace supplémentaire ajouté, vous pouvez utiliser une méthode de composition (voir les sections suivantes) pour composer une image dans cet espace. Vous pouvez ainsi préparer un libellé bien plus élaboré à ajouter à l'animation. Bien sûr, faire cela peut empêcher certaines animations de bien s'optimiser ensuite, en particulier les animations à image effacée, mais c'est le prix à payer pour ajouter des libellés. Une solution pour ce type d'animation est d'ajouter en tête un « canevas d'arrière-plan initial » qui contient le libellé, comme le montre la section expliquant les animations à image effacée. Notez aussi qu'ajouter un libellé à une animation peut entraîner l'ajout de nombreuses couleurs supplémentaires. Cela pourrait dépasser les limites de couleurs du GIF, si bien que vous devrez peut-être vous préparer à optimiser aussi les couleurs de votre animation. Une tâche très difficile qu'il vaut mieux éviter si possible (voir Optimisation des couleurs). Cela peut poser problème pour toute modification générale de toute animation.

Supprimer la transparence - ajouter un fond de couleur unie

Un grand nombre d'animations que l'on trouve sur le web ont un fond transparent. Elles sont très pratiques, car vous pouvez les placer sur des pages web sans vous soucier d'un éventuel motif d'arrière-plan présent. Cependant, lors du traitement d'animations, en particulier lorsqu'on applique d'autres opérateurs d'image comme « [-resize](https://imagemagick.org/command-line-options/#resize) » et « [-blur](https://imagemagick.org/command-line-options/#blur) », une telle animation pose problème. La solution générale consiste à supprimer la transparence de l'image, généralement en la superposant d'une manière ou d'une autre sur une couleur précise, par exemple la couleur utilisée comme fond d'une page web. [IM Output] Par exemple, j'ai ici une simple animation de surimpression transparente d'une lettre « K » qui se dessine comme par une main invisible. Comme cette animation GIF est dessinée avec de la transparence, et qu'elle ne fait que superposer des images sur les images précédentes (en ajoutant des pixels, jamais en les retirant), une façon simple de définir une couleur (ou une image) de fond est de l'ajouter uniquement à la première image de l'animation. Toutes les autres images contiennent une couleur transparente pour l'arrière-plan, elles n'affecteront donc pas le résultat. Ici, nous utilisons l'opérateur d'aplatissement (flatten) pour superposer la première image de l'animation sur une couleur de fond « LimeGreen ». Nous pouvons utiliser « [-flatten](https://imagemagick.org/command-line-options/#flatten) » ici, car nous l'appliquons uniquement à une seule image, et NON à toute l'animation. |

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

[IM Output]
Il est aussi important de noter que la première image d'origine ne faisait qu'un seul pixel. L'opérateur d'aplatissement (flatten) n'a pas seulement coloré l'arrière-plan, il a aussi agrandi cette image à sa taille complète. Autrement dit, il a aussi « rempli » l'image. Notez cependant que seule la première image de l'animation a été colorée. Cette méthode est préférée, car toute optimisation (comme la lourde optimisation que contient cette animation) est préservée. Colorer la première image ne fonctionnera pas pour toutes les animations GIF. Cela ne fonctionne que pour de simples animations de surimpression. Pour une méthode générale de suppression de la transparence d'une animation, vous devez d'abord « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) » l'animation, puis supprimer la transparence de toutes les images à l'aide de l'opérateur de suppression alpha. Cette fois, faisons-le avec une couleur de fond « Tomato ». |

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

[IM Output]
Bien sûr, l'optimisation résultante ne sera peut-être pas aussi optimale que l'originale, mais l'animation ne contient plus aucune transparence. Effet secondaire supplémentaire : tout réglage de disposal « [Background](anim_basics.html#background) » présent dans l'animation aura été converti en « [None](anim_basics.html#none) » ou « [Previous](anim_basics.html#previous) » par le processus d'optimisation d'image, la transparence n'étant plus un problème. | Lasuppression alpha a été ajoutée à IM v6.7.5. Si votre version d'IM est plus ancienne, vous devrez recourir à une méthode alternative, par exemple en exploitant un effet secondaire de l'opérateur de bordure (border). Voir Supprimer la transparence pour les détails de cette méthode et d'autres.
---|---
Une gestion de fond plus complexe, comme le sous-calquage d'une image ou d'un motif d'arrière-plan, nécessite une manipulation des animations bien plus complexe que les simples modifications que nous avons examinées jusqu'ici. C'est ce que nous allons voir maintenant.


Composition alpha multi-images

Le niveau suivant de manipulation d'animation exige de pouvoir composer des images statiques uniques, soit par-dessus, soit par-dessous une animation existante. C'est-à-dire une composition alpha générale. Cela devient encore plus délicat lorsque deux ensembles distincts d'images sont fusionnés. Avant IM v6.3.3-7, la composition multi-listes n'était possible qu'à l'aide de scripts d'API spécialement conçus, ou de scripts shell qui enregistraient et fusionnaient les images individuelles de l'animation. Aucune de ces techniques n'était très agréable, mais c'était tout ce qui était possible. Cela a désormais changé.

Dessiner des images - dessiner une image sur une liste d'images

L'opérateur « [-draw](https://imagemagick.org/command-line-options/#draw) » a la capacité de composer une image source par-dessus une liste d'images. C'est aussi la seule méthode de composition alpha multi-images que vous pouviez utiliser dans la commande « [mogrify](basics.html#mogrify) », ou sur plusieurs images, avant IM v6.3.3-7. La raison pour laquelle cette technique de composition alpha était si importante, c'est qu'elle vous permettait de spécifier une image comme argument distinct de la liste d'images en cours. C'est-à-dire, au sein du langage Magick Vector Graphic mis entre guillemets de « [-draw](https://imagemagick.org/command-line-options/#draw) ». En raison de son importance historique, j'en montrerai l'utilisation en détail, notamment pour les utilisateurs qui ont encore d'anciennes versions d'IM. Par exemple, ici je superpose l'image de la rose sur toute l'animation. |

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

[IM Output]
Cela vous permet de composer une image source externe par-dessus chaque image de la séquence d'images en cours. C'est suffisant pour la plupart des usages. Par exemple, en utilisant la méthode de composition « [Dst_Over](compose.html#dstover) », vous pourriez aussi placer une image « sous » l'animation comme fond statique. Par exemple, ici nous « sous-calquons » une image intégrée « netscape: », même si cela aurait pu être n'importe quel fichier image externe... |

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

[IM Output]
Notez que la taille de l'animation n'a pas changé, car ce sont les images de destination qui définissent la taille finale de la composition alpha. Si vous vouliez créer un canevas plus grand, vous deviez ajuster la taille et les décalages de l'animation en conséquence pour accommoder le fond. Par exemple, en utilisant un repage relatif de l'animation avant la fusion. |

  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]
De même, si vous vouliez utiliser une image qui avait déjà été lue, créée ou modifiée, vous devez alors utiliser un MPR : Memory Program Register pour vous fournir une « source de lecture » pour cette image. |

  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]
C'est à peu près la limite des méthodes de composition alpha par dessin. Pas de superposition des images de l'animation « par-dessus » une image de destination de taille inconnue, et aucun moyen de fusionner deux séquences multi-images distinctes. C'était le cas jusqu'à...

Composition en couches - composition alpha pour les listes d'images

Avec IM v6.3.3-7, la méthode « **Composite** » de « [-layers](https://imagemagick.org/command-line-options/#layers) » a été ajoutée, permettant de composer ensemble deux ensembles d'images complètement distincts. (Pour un bref résumé, voir Superposer les images, composition de couches). Pour faire cela en ligne de commande, une image marqueur spéciale « [null:](files.html#null) » est nécessaire pour définir où se termine la première liste d'images de destination et où commence la liste d'images source superposée. Mais c'est la seule véritable complication de cette méthode. Essayons-la donc en créant un ensemble d'ombres à partir d'un ensemble d'images, puis en superposant l'image d'origine par-dessus ces images d'ombre... |

  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]

L'exemple ci-dessus est très important, je vais donc l'expliquer en détail. Nous générons d'abord une version fusionnée de notre animation afin de supprimer toute optimisation éventuellement présente et de préparer l'animation à un traitement sérieux, sans qu'aucune optimisation GIF n'interfère avec le traitement. Ensuite, nous créons une image d'ombre animée à partir de notre animation fusionnée, et nous supprimons la transparence, car le GIF ne peut pas gérer les ombres semi-transparentes. C'est l'animation que nous voulons ajouter « sous » notre animation d'origine. Elle a le même nombre d'images, et même les mêmes timings que l'animation d'origine. Cette correspondance est importante, alors ne l'oubliez pas. Maintenant, nous lisons les deux animations ou séquences de couches, mais nous ajoutons entre elles une image séparatrice « [null:](files.html#null) » spéciale, afin qu'ImageMagick sache où une séquence se termine et où la suivante commence. Cette image séparatrice est automatiquement supprimée par l'opération « -layer composite » cruciale qui suit. D'autres API devraient pouvoir utiliser des « Wands » d'images distincts, plutôt qu'une seule séquence avec un séparateur spécial. La composition en couches est alors effectuée exactement comme si ces deux animations ou séquences d'images n'étaient qu'une simple image unique, plutôt qu'une séquence de plusieurs images. Chaque paire d'images, une de destination et une source, est composée ensemble, pour générer une séquence d'images fusionnées (composées). Le résultat final est que nous avons ajouté des ombres à notre séquence d'animation d'origine, prête pour les optimisations GIF, ou pour un usage direct.
Vous pouvez désormais réaliser toutes les étapes ci-dessus en une seule commande. Vous ne pouvez cependant pas simplement utiliser « [-clone](https://imagemagick.org/command-line-options/#clone) » pour créer une copie de la séquence d'origine, car nous ne savons pas vraiment (et ne voulons pas savoir) combien d'images contient la séquence. À la place, vous pouvez utiliser un MPR : Memory Program Register pour enregistrer une liste entière d'images. C'est un peu comme prendre un instantané de toute la séquence d'images actuellement en mémoire, puis la relire plus tard. Le résultat est une commande comme celle-ci, bien que j'aie utilisé une couleur de fond différente. |

  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]
Cette version fonctionne en réalité mieux, car nous n'avons pas perdu l'information de décalage que génère l'opérateur d'ombre (shadow) (les GIF ne peuvent pas enregistrer de décalage négatif, ils le remettent donc à zéro). Nous pourrions corriger cela ci-dessus en utilisant un format de fichier MIFF pour les images intermédiaires plutôt que le GIF, ou, comme vous le verrez dans l'exemple suivant, en utilisant un décalage de composition « [-geometry](https://imagemagick.org/command-line-options/#geomtry) ». Fondamentalement, ces exemples montrent que l'opérateur de composition de couches comprend en réalité les réglages individuels de décalage de canevas virtuel (« [-page](https://imagemagick.org/command-line-options/#page) ») et les gérera, tout comme le feraient les opérateurs de aplatissement de couches ou, mieux encore, de fusionnement de couches (merge). Mais l'opérateur de composition de couches comprend aussi l'utilisation d'un décalage de géométrie de composition (« [-geometry](https://imagemagick.org/command-line-options/#geometry) », nul par défaut), pour contrôler le placement global de toute la séquence d'images superposée. Il comprend même les effets de « [-gravity](https://imagemagick.org/command-line-options/#gravity) » sur ce décalage global. Par exemple... superposons notre animation « K » d'origine au « sud » de l'animation d'ombre générée... |

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

[IM Output]
Ce qui précède montre aussi que, tout comme la composition alpha normale à deux images, c'est la séquence d'images de destination qui contrôle la taille de l'image de sortie finale, et toute surimpression de composition sera rognée au canevas de destination. Vous devez donc veiller à ce que toutes les images de destination soient assez grandes pour contenir vos résultats finaux. | La capacité de redimensionnement de « [-geometry](https://imagemagick.org/command-line-options/#geometry) » ne fait pas strictement partie de l'opération de composition, elle ne redimensionne que la dernière image de la séquence d'images en cours. Elle ne fera donc pas ce que vous attendez si elle est utilisée avec une composition de couches multi-images. Voir Géométrie de redimensionnement pour les détails.
---|---
Fondamentalement, la composition en couches ressemble beaucoup à la composition normale.
Tout simplement, vraiment. Ai-je dit simple ?
Détails de la composition en couches......Comme vous l'avez vu ci-dessus, la version en ligne de commande de « [-layers](https://imagemagick.org/command-line-options/#layers) Composite » utilise la première image « [null:](files.html#null) » trouvée dans la liste d'images en cours comme marqueur pour séparer les deux listes. Les deux listes d'images sont séparées et la « null: » est jetée avant que les deux listes ne soient composées en alpha, deux images à la fois. Seule une image générée à partir de la source d'image spéciale « [null:](files.html#null) » peut servir de marqueur, et si aucune n'est trouvée, une erreur est signalée. Vous ne pouvez actuellement pas lire cette image marqueur « [null:](files.html#null) » depuis un pipeline (du moins pas pour l'instant), il faut la générer au besoin. La composition de couches est aussi un peu plus complexe qu'une simple composition alpha à deux images, car le canevas virtuel des images de la liste est aussi pris en compte. Normalement, la composition alpha ignore toute taille et tout décalage de canevas virtuel à des fins de positionnement, en n'utilisant que la taille réelle des images. Cette méthode de couches spéciale utilise l'information du canevas virtuel, pour le positionnement de la géométrie, afin d'aligner les deux séquences d'images. À cette fin, tout décalage de canevas virtuel qu'a une sous-image est aussi ajouté au décalage de composition « [-geometry](https://imagemagick.org/command-line-options/#geometry) » ajusté par la « [-gravity](https://imagemagick.org/command-line-options/#gravity) » normale, pour déterminer la position de la surimpression d'image. Seule la taille du canevas virtuel « [-page](https://imagemagick.org/command-line-options/#page) » de la première image de chaque liste est utilisée pour déterminer l'ajustement de « [-gravity](https://imagemagick.org/command-line-options/#gravity) » sur le décalage de composition « [-geometry](https://imagemagick.org/command-line-options/#geometry) ». La taille du canevas des images ultérieures est ignorée, seul le décalage individuel du canevas virtuel « [-page](https://imagemagick.org/command-line-options/#page) » étant ajouté au décalage « [-geometry](https://imagemagick.org/command-line-options/#geometry) » calculé. Autrement dit, « [-layers](https://imagemagick.org/command-line-options/#layers) Composite » est conçu pour la composition alpha de « couches » ou d'« animations », et pour les exigences particulières de telles listes d'images. Mises en garde...Vous devez néanmoins rester prudent avec les listes d'images que vous superposez. Si, par exemple, les images de la liste de destination ne sont pas assez grandes, ou sont mal positionnées pour contenir l'image source superposée, l'image superposée sera rognée, ou manquera complètement l'image de destination. Pour cette raison, il est judicieux de fusionner (coalesce) les images de destination à la taille complète du canevas avant de superposer des images source plus petites. Voir par exemple les exemples de concaténation côte à côte d'animation ci-dessous, où la taille du canevas devait être agrandie pour laisser de la place aux images concaténées. De plus, si la liste d'images source est une animation GIF, vous devrez peut-être vous assurer que les sous-images sont exemptes de choses comme les optimisations de compression et les optimisations d'image sophistiquées ; sinon vous risquez d'avoir des problèmes. En revanche, une animation à image effacée ou une animation fusionnée peut être directement « [Composite](#composite) » sans aucun problème. Rappelez-vous simplement que la composition en couches ne comprend aucune méthode de disposal GIF éventuellement présente dans les images, bien qu'elle préserve les métadonnées de l'animation GIF de destination, comme : la méthode de disposal, le délai d'image et les limites de boucles d'itération. La seule exception à cela est donnée dans un cas particulier ci-dessous.

Composition avec une seule image - composer des images avec une image unique

Normalement, deux listes d'images de longueur égale sont composées ensemble, une paire d'images à la fois, jusqu'à ce que l'une des listes soit épuisée. Aucune des listes d'images ne sera répétée. La composition s'arrête simplement. Il vous reste juste la liste d'images de destination d'origine avec les compositions ajoutées. L'image séparatrice « [null:](files.html#null) » et toutes les images source sont supprimées de la liste d'images en cours. Une interface d'API à cette méthode de couches devrait vous permettre de produire deux listes d'images distinctes, et il vous appartiendra de supprimer les deux listes d'images d'entrée utilisées pour générer la liste d'images résultante. Le séparateur « [null:](files.html#null) » ne devrait pas être nécessaire.
Cependant, si l'une des listes ne contient qu'une seule image, cette image sera composée contre toutes les images de l'autre liste. Peu importe que cette image unique soit une image source ou une image de destination. La méthode effectuera la composition contre l'autre liste d'images, et préservera les métadonnées GIF de la liste d'images, plutôt que celles de l'image unique, même si cette image est l'image de destination. Cette « composition contre une image unique » est un cas particulier de la composition en couches, et est très utile pour ajouter un fond à une animation (voir ci-après), ou pour insérer un objet statique dans une animation.

Fond statique - composer sur un fond plus grand

Par exemple, en utilisant cette méthode spéciale de composition de couches avec une seule image, nous pouvons composer une animation sur un fond statique... |

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

[IM Output]
Comme l'image de fond est la destination, elle définit la taille finale de l'animation, mais toutes les métadonnées (délais, libellés, commentaires, etc.) proviendront de la liste d'images source. Normalement, ces informations proviennent de la liste d'images de destination. C'est la seule fois où l'image source fournit les informations de métadonnées lors d'une composition d'images. Notez aussi que, comme la composition en couches comprend « [-gravity](https://imagemagick.org/command-line-options/#gravity) », l'image est correctement centrée sans que vous ayez à faire les calculs vous-même. Cependant, si les images source contenaient des décalages, ceux-ci seront aussi ajoutés à la position définie par la gravité, de sorte que la position relative de toutes les sous-images reste correcte. Notez que, comme l'animation « [script_k.gif](../static/img/images/script_k.gif) » est en réalité un type d'animation de surimpression, il existe d'autres méthodes pour ajouter un fond statique à l'animation. Voir la section ci-dessus sur Supprimer la transparence pour un exemple (sur une couleur unie, mais cela peut être n'importe quelle image). Il en va de même pour l'animation à image effacée, encore plus simple. Dans ce cas, vous n'avez même pas besoin de fusionner (coalesce) l'animation d'abord, vous pouvez la composer directement sur une image de fond. Vous devrez toutefois peut-être « [-set](https://imagemagick.org/command-line-options/#set) » la méthode « dispose » utilisée ensuite, ou mieux encore optimiser l'animation entièrement fusionnée. Cependant, tout autre type d'animation optimisée nécessitera cette opération « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) », et une composition complète avec toutes les images de l'animation. Il vaut donc probablement mieux utiliser la méthode ci-dessus, juste pour être sûr que toutes les animations GIF sont correctement gérées.


Tout ce qui brille...

Animations de paillettes

Les méthodes de composition en couches ci-dessus facilitent grandement la génération d'animations simples, comme des paillettes. Il nous faut d'abord des paillettes assez grandes pour couvrir l'image traitée. Ici, je vais générer une animation de paillettes de trois images à partir de quelques images de mouchetures aléatoires. Il s'agit d'abord de paillettes brutes en noir et blanc sur transparence pure, générant 3 images de paillettes en séparant les trois canaux de couleur en images de canaux en noir et blanc. C'est fondamentalement un point de départ brut pour générer tout autre type de paillettes. Le seuil « 30% » contrôle le nombre de « points » par image. |

  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]
À partir de ces paillettes « brutes », vous pouvez les superposer à l'aide d'une composition alpha « [Screen](compose.html#screen) » pour n'éclaircir que certaines couleurs, afin de générer des paillettes d'une couleur précise. J'utilise la méthode d'aplatissement par bordure (ci-dessus). Simplement une couleur unie... |

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

[IM Output]
En utilisant la composition de couches, vous pouvez aussi utiliser une seule image, voire plusieurs images, pour fournir un fond de couleur variable. Par exemple, ici je génère trois images de plasma fractal, pour donner une coloration légèrement aléatoire au motif de paillettes. |

  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]
Bien sûr, il existe de nombreux autres styles de paillettes et motifs de mouvement. Vous pouvez trouver et télécharger de nombreuses tuiles de paillettes de ce type sur le web. Pour appliquer des paillettes de ce genre à une image, il existe plusieurs méthodes différentes. Typiquement, vous masquez les paillettes selon une forme précise et/ou un fond. Pour cela, vous pouvez utiliser soit une forme transparente (composée à l'aide de 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]

Soit une image de masque en noir et blanc (composée à l'aide de CopyOpacity)

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

[IM Output] [IM Output]

Bien, nous avons une zone qui a été masquée ; vous pouvez compléter l'image, généralement en superposant les paillettes masquées sur l'image d'origine. Dans notre cas, cependant, je vais sous-calquer un fond et superposer une bordure. |

  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]
Ce dernier exemple a aussi corrigé tout problème de transparence GIF en supprimant toute transparence de l'image finale et en superposant une bordure lisse autour de la région pailletée. | Bien que j'aie pu utiliser des images au format GIF ci-dessus pour me permettre d'utiliser magick display afin d'afficher les étapes individuelles du processus, en pratique vous combineriez soit toutes les étapes en une seule commande, soit vous utiliseriez un meilleur format de fichier image intermédiaire comme le MIFF. Cela, pour éviter les problèmes inhérents au format GIF, jusqu'à ce que nous ayons terminé.
---|---

Tuiles de paillettes - sous-couches par « trou dans l'image »

Comme mentionné, il existe de nombreuses images de tuiles de paillettes animées prêtes à l'emploi sur le web (faites une recherche pour « glitter tiles »). Une source est un utilisateur de IM Studio, scri8e et son site web Moons Stars. Attention cependant : je trouve la plupart des tuiles de paillettes plutôt affreuses, ou trop rapides. Pour cet exemple, j'ai trouvé et modifié une tuile de paillettes bleues comportant quelques petits motifs d'étoiles. J'ai pensé qu'elle serait utile pour donner au sorcier d'IM un vêtement scintillant, le faisant paraître vraiment magique. La façon probablement la plus simple d'ajouter des paillettes à une image existante est d'y découper des trous plutôt que d'essayer de masquer le motif de paillettes. Cela ne fonctionne toutefois que pour les images qui ne contiennent pas de transparence au départ. Sinon, vous pourriez supprimer la transparence d'une image et, une fois terminé, réappliquer la transparence d'origine. Prenons donc le logo des Exemples IM et utilisons le remplacement de couleur pour découper toutes les parties bleues de l'image. Une façon de donner à notre sorcier une cape d'invisibilité ;-)

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

[IM Output] [IM Output]

Remarquez l'utilisation du facteur de flou (fuzz) pour ajuster la quantité de couleur bleue à supprimer. Attention toutefois : ce n'est pas une belle façon de découper une zone d'une image, car cela produit des bords crénelés. Mais aucune fonction simple de découpe avec adoucissement des bords n'est encore disponible pour l'instant. Bon, nous avons une image avec un trou (ou beaucoup de trous). L'étape suivante consiste à sous-calquer l'image de tuile de paillettes. Le problème est que la tuile ci-dessus est trop petite, elle ne couvrira pas toute l'image ! Ce qui suit utilise une technique astucieuse pour carreler la tuile de paillettes multi-images. Vous devez toutefois donner une taille plus grande que l'image d'origine pour vous assurer de pouvoir la couvrir complètement. |

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

[IM Output]
Habillons maintenant notre sorcier de ses nouveaux vêtements, en plaçant les paillettes carrelées ci-dessus sous l'image « trouée ». |

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

[IM Output]
Vous pouvez bien sûr réaliser toutes ces étapes en une seule commande. Ici, je limite la génération de trous à la seule cape du sorcier, qui comporte deux parties spécifiques distinctes. |

  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]
Les trous ci-dessus ont été créés à l'aide des primitives de dessin Matte Fill pour sélectionner un point et une couleur réels de l'image en vue du remplacement de couleur. Cela signifie que je n'ai pas besoin d'utiliser un facteur de flou (fuzz) aussi élevé qu'à l'origine, puisque ma couleur de comparaison provenait des zones spécifiques sélectionnées. J'ai aussi utilisé une « fenêtre d'affichage » de carrelage plus grande afin de m'assurer de couvrir complètement l'image carrelée, sans avoir besoin de connaître ses dimensions exactes. | _L'utilisation de l'opérateur de distorsion générale et de son option spéciale « viewport » (ajoutée à IM 6.3.6-0) vous donne aussi la possibilité de modifier le motif de distorsion d'autres façons particulières. Par exemple, lui donner un aspect de « perspective » ou faire pivoter le motif selon des angles non rectangulaires. Cela peut améliorer le carrelage pour qu'il n'ait pas un aspect aussi uniforme.

Pour quelques exemples, voir Carrelage affine._
---|---

Scintillements - superposer des paillettes majoritairement transparentes

Le problème majeur des deux techniques d'animation de paillettes précédentes est qu'il s'agit d'un remplacement de type tout ou rien. Vous ne pouvez pas utiliser l'ombrage ou le fond d'origine de l'image. De plus, les paillettes sont complètement restreintes à la zone masquée. Elles ne peuvent pas s'étendre au-delà des limites de la zone concernée. Ainsi, certaines petites zones, comme le « chapeau » du sorcier dans l'exemple précédent, ne gèrent pas très bien les paillettes. Les scintillements sont différents, en ce que l'animation ajoutée est majoritairement transparente. En conséquence, l'image d'origine peut encore transparaître. De telles animations s'ajoutent généralement à une image de l'une des deux façons suivantes. Soit la surimpression d'animation elle-même est transparente, soit elle prend la forme d'un fond noir avec des « étincelles » blanches là où l'image doit être éclaircie.

En cours de rédaction

Voici un exemple de surimpression de « scintillements » majoritairement transparente. Exemple ici Comme vous pouvez le voir, vous pouvez avoir des surimpressions de scintillements colorées lorsque cette forme est utilisée. Le problème majeur, c'est qu'une animation GIF a été utilisée pour l'enregistrer (ce qui est généralement le cas), si bien que la surimpression est fortement crénelée. C'est-à-dire qu'elle ne peut contenir aucun pixel semi-transparent pour adoucir l'aspect de l'image superposée. Si c'était le cas, vous obtiendriez d'horribles halos noirs autour des « étincelles » dans le résultat final. Masquons et superposons ceci sur le sorcier. Exemple ici L'autre forme de scintillements est celle des étincelles blanches sur fond noir (une image en niveaux de gris). Elles sont masquées et superposées de manière à éclaircir l'image pour ajouter le scintillement. Par exemple... Exemple ici L'un des meilleurs atouts des scintillements est que vous pouvez générer une séquence d'images où les étincelles apparaissent lentement puis disparaissent. Cela peut devenir assez complexe, mais ce n'est pas très difficile à faire. Exemple ici

Ajouter des animations d'éclats et d'étoiles

Là où les paillettes consistent en points de luminosité isolés, et où les scintillements peuvent recouvrir certaines zones d'une image, les éclats sont généralement ajoutés individuellement. Un « éclat » est fondamentalement un point qui s'illumine pour couvrir une grande zone l'espace d'un instant. Une « étoile » est similaire, sauf que la couverture prend davantage la forme de « rayons » de luminosité. Ils sont généralement « semés » à partir de points précis, mais le résultat s'étend souvent, au moins momentanément, bien au-delà de la zone d'ensemencement. Par exemple, un éclat limité par masque à une zone précise a l'air très, très stupide et peu naturel. Les aspects les plus difficiles des éclats sont de repérer de bons points d'« ensemencement » et de synchroniser correctement les multiples éclats.

En cours de rédaction

Exemple final que je veux créer...  Un « scintillement » qui remonte la
baguette du sorcier, puis éclate, et se dissout en un certain nombre de petits
éclats scintillants sur une zone.  Puis la séquence se répète.

Redimensionner les animations

Problèmes de redimensionnement des animations

Le plus gros problème du redimensionnement des animations GIF est que l'opérateur « [-resize](https://imagemagick.org/command-line-options/#resize) » est conçu spécifiquement pour rendre les images résultantes aussi proches que possible de l'idéal (après le redimensionnement). Pour cela, il fusionne et génère beaucoup de couleurs supplémentaires dans l'image afin de la rendre plus belle. Les images résultantes sont loin d'être idéales pour un enregistrement dans le format de fichier GIF limité. Avec la table de couleurs limitée du GIF, cela entraîne de fortes réductions de couleurs dans les images redimensionnées. Pour une image GIF unique, ce n'est pas si grave, mais pour les animations GIF, le tramage par correction d'erreur par défaut de l'ensemble de couleurs réduit produit des problèmes, sous forme de « bruit de tramage » entre les images, et à son tour une mauvaise optimisation d'image pour la taille finale du fichier. C'est encore pire lorsque des couleurs transparentes sont aussi utilisées, ce qui est une pratique courante pour les animations GIF typiques utilisées sur les pages web. La transparence est aussi couramment utilisée pour les techniques d'optimisation de compression, pour des animations qui n'en auraient sinon pas besoin. Ce qui se passe, c'est que « [-resize](https://imagemagick.org/command-line-options/#resize) » produit des pixels semi-transparents dans les images de surimpression. Puis, lorsque les images sont réenregistrées au format GIF, ces pixels sont convertis soit en entièrement transparents, soit en entièrement opaques, les deux produisant des distorsions de couleur majeures dans l'animation résultante. Si une quelconque forme d'optimisation est utilisée... d'image, de transparence ou LZW... alors les effets de transparence aboutiront fondamentalement à une animation GIF redimensionnée désastreuse. Ce sont les faits, mon ami ! Vous devrez donc faire avec. Même si vous évitez d'utiliser « [-resize](https://imagemagick.org/command-line-options/#resize) » en recourant à « [-sample](https://imagemagick.org/command-line-options/#sample) », vous aurez encore des problèmes majeurs à moins de « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) » l'animation d'abord.

Techniques de redimensionnement d'animations

Comme montré ci-dessus, il existe de sérieux problèmes de redimensionnement des animations GIF, dont aucun ne se résout facilement. La solution dépend aussi généralement du type d'image qui a été redimensionnée au départ, qu'elle soit de type dessin animé ou une image vidéo du monde réel. Voici les méthodes que je connais, ou qui ont été proposées...

Éviter le redimensionnement

Si c'est le moindrement possible, NE REDIMENSIONNEZ PAS. Vous pouvez par exemple appliquer un rognage de canevas ou par fenêtre d'affichage à votre animation pour simplement la réduire afin qu'elle tienne dans l'espace dont vous avez besoin. Ou bien vous pouvez générer l'animation GIF à la bonne taille dès le départ. Aucune de ces deux techniques n'est généralement la meilleure option, mais si vous le pouvez, envisagez-la, car elle vous épargnera bien des problèmes et des cheveux arrachés.

Redimensionnement direct

Comme mentionné, utiliser directement « [-resize](https://imagemagick.org/command-line-options/#resize) » posera des problèmes, soit avec le nombre de couleurs de chaque image, soit avec les couleurs semi-transparentes. Par exemple, ceci tourne vraiment mal... |

  magick script_k.gif -resize 20x20 script_k_direct.gif

[IM Output]
[IM Output]
Cela n'a pas très bien fonctionné, et c'est parce que l'image d'origine comporte de fortes optimisations d'image. Chaque « image » de l'animation n'est pas de la même taille, et « [-resize](https://imagemagick.org/command-line-options/#resize) » redimensionnera chacune des images complètement séparément des autres. Autrement dit, ce qui précède a redimensionné les images réelles, et non le canevas virtuel de l'animation, à la taille donnée. En fait, je suis surpris que l'animation résultante ne soit pas plus « folle » que la simple zone vide montrée. Cela nous amène au premier point concernant le redimensionnement des animations. Assurez-vous d'abord que toutes les images sont entièrement définies, et que TOUTE optimisation a été supprimée. Autrement dit, fusionnez (coalesce) l'animation avant d'essayer de la redimensionner. Par exemple... |

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

[IM Output]
[IM Output]
Le problème suivant est celui des couleurs de transparence. Si vous regardez le résultat ci-dessus, vous verrez que les bords de l'animation plus petite sont horriblement crénelés (« en escalier »). C'est parce que le GIF ne peut pas enregistrer les couleurs semi-transparentes que l'opérateur « [-resize](https://imagemagick.org/command-line-options/#resize) » a générées. Les couleurs à l'intérieur de l'objet animé auront aussi été fusionnées pour produire de nouvelles couleurs, mais ce n'est généralement pas aussi grave que le crénelage des bords.

Redimensionner avec aplatissement, une solution générale.

La meilleure idée lors de la génération d'une vignette GIF est d'éviter entièrement les problèmes de transparence. C'est-à-dire, aplatir l'animation, avant ou après l'avoir redimensionnée. Ainsi, vous ne perdez pas l'« anticrénelage » des bords dans les images redimensionnées. En fait, j'ai constaté que la plupart des bons sites web d'animations GIF font exactement cela lorsqu'ils génèrent leurs vignettes d'animations GIF. Bien sûr, la vignette sera alors limitée à un usage sur un fond d'une couleur précise, généralement « blanc », mais parfois « noir » ou « argenté » (le gris des pages web), bien que ce dernier soit moins courant de nos jours. Par exemple, ici je crée une vignette plus petite sur une couleur de fond appropriée pour cette page web. |

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

[IM Output]
[IM Output]
C'est la solution recommandée pour la gestion générale des vignettes GIF. Toute autre méthode nécessite soit un contrôle humain, soit une logique de gestion des vignettes GIF très sophistiquée.

Explosion de la table de couleurs

Le plus gros problème (comme je l'ai mentionné au début de cette section) est qu'un très grand nombre de couleurs supplémentaires sont générées dans l'image, en particulier près des lignes et des bords des zones de couleurs adjacentes. Vous obtenez aussi un halo de redimensionnement de couleurs semi-transparentes autour des bords des images. Cela agrandit à son tour la table de couleurs nécessaire pour une simple animation aux couleurs minimales, ce qui signifie à son tour une taille de fichier plus grande lorsqu'une animation simple redimensionnée est enregistrée. Pire encore, chacune des images de l'animation redimensionnée génère probablement un ensemble de couleurs différent, ce qui agrandit encore la taille de fichier de votre animation « en vignette ». Il y a aussi le problème qu'après quantification des couleurs, vous n'aurez peut-être plus exactement les mêmes couleurs que l'animation d'origine (voir La quantification ne préserve PAS les couleurs). Autrement dit, au lieu d'avoir une simple zone de blanc pur, vous pourriez maintenant avoir une zone d'un blanc cassé.

Redimensionner à l'aide de Sample

Pour éviter de générer des couleurs supplémentaires lors du redimensionnement, la façon la plus simple est de « [-sample](https://imagemagick.org/command-line-options/#sample) » l'animation, plutôt que de la redimensionner. Cela préservera les couleurs actuelles de l'animation et vous permettra de réoptimiser facilement l'animation à la nouvelle taille. |

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

[IM Output]
[IM Output]
Cependant, bien que cela fonctionne, vous supprimez fondamentalement des lignes et des colonnes de pixels de l'image, perdant au passage des données d'image et donc de la qualité. Avec les images de type dessin animé, cela laisse souvent des bords « en pointillé », et des détails manquants ou déformés. Si votre redimensionnement dépasse 50 % de la taille d'origine de l'animation, comme c'est le cas ci-dessus, le résultat est souvent assez horrible, surtout quand une texture ou un autre motif de couleur est utilisé dans l'animation. Il n'est donc pas surprenant que de nombreuses bibliothèques d'animations GIF soient remplies de telles horribles animations redimensionnées par échantillonnage, qu'elles ont copiées un peu partout sur le net. Je souhaiterais souvent qu'elles nettoient ce genre de camelote, mais cela signifierait réduire le nombre de GIF proposés, ce qui réduit à son tour les statistiques marketing du nombre de GIF disponibles, ce que le service publicité n'apprécie pas. En conséquence, les animations GIF de mauvaise qualité sont courantes.

Redimensionner à l'aide du Liquid Resize

Une méthode similaire à celle de Sample ci-dessus consiste à utiliser le Liquid Rescale, aussi connu sous le nom de Seam Carving. Cela supprime ou ajoute aussi des pixels entiers des images concernées, mais tente de le faire d'une manière qui préserve autant que possible la complexité de l'image. Consultez les liens ci-dessus pour voir comment l'utiliser pour générer de plus belles images redimensionnées. Malheureusement, il n'y a pour l'instant aucun moyen de l'utiliser sur une image animée générale, car il n'a pas de compréhension de la complexité d'une image, et nous ne pouvons pas actuellement extraire la méthode de rééchelonnement pour l'appliquer de façon cohérente à chaque image d'une animation. Espérons que cela changera à un moment donné à l'avenir.

Redimensionner et restaurer les couleurs

Échantillonner une animation ne fait que supprimer des lignes et des colonnes de pixels, avec la possible suppression de lignes fines et d'autres détails importants. Mais fusionner les pixels à l'aide de « [-resize](https://imagemagick.org/command-line-options/#resize) » produit beaucoup trop de nouvelles couleurs pour le format GIF. La solution évidente est donc de faire le « [-resize](https://imagemagick.org/command-line-options/#resize) », puis d'utiliser les couleurs de l'animation d'origine pour restaurer les couleurs de l'animation redimensionnée, en utilisant une palette de couleurs (colormap).

FUTURE: exemple avec table de couleurs d'origine restaurée

Cela a l'avantage supplémentaire de ne pas générer de tables de couleurs locales. Les résultats peuvent toutefois être meilleurs avec le tramage désactivé, afin d'éviter tout « bruit de tramage ». C'est particulièrement vrai pour les images de type dessin animé qui comportent de grandes zones de couleur uniforme.

FUTURE: exemple de table de couleurs restaurée sans tramage

Optimisation complète des couleurs

Si une horrible vignette échantillonnée n'est pas à votre goût, alors vous êtes confronté à la perspective de procéder à une optimisation des couleurs complète de l'animation GIF redimensionnée. Pour déterminer précisément quelles « nouvelles » couleurs vous voulez que l'animation conserve. Ce n'est cependant souvent pas si grave pour la plupart des animations, mais cela peut être un effort majeur pour des animations plus complexes, comme lors de la conversion d'une vidéo en animation GIF. Autrement dit, si vous avez affaire à une animation de type dessin animé, vous aurez maintenant des lignes et des bords fortement anticrénelés. Pour les animations qui impliquent un fond transparent, vous devrez aussi gérer correctement les pixels semi-transparents autour du bord de votre animation, eux aussi causés par les fonctionnalités d'anticrénelage du redimensionnement. Voir la section sur la transparence booléenne GIF pour les nombreuses méthodes que vous pouvez utiliser pour gérer cela.

Fortes réductions de taille

Lorsque vous prévoyez de redimensionner une grande animation en une animation beaucoup plus petite, vous êtes confronté au problème de la disparition de parties importantes de l'animation. C'est en fait un problème pour les images statiques comme pour les animations. Voir Redimensionner les dessins au trait pour toutes les solutions connues à cela.
Toute autre suggestion, idée ou technique est la bienvenue.


Fusionner plusieurs animations

Je l'ai déjà dit, mais cela devient particulièrement important lors de la fusion d'animations...

Sachez-en autant que possible sur l'animation avec laquelle vous travaillez !

Le script « [gif2anim](../static/img/scripts/gif2anim) » est idéal à cette fin. Son script jumeau « [anim2gif](../static/img/scripts/anim2gif) » est aussi couramment utilisé ici pour recréer une animation à l'aide de ses réglages d'origine. (Voir l'usage de base du script dans Informations sur la liste d'animation.) Sans connaître le fonctionnement d'une animation, il est quasi impossible de les fusionner de diverses manières. Des programmes peuvent être développés (le but ultime de ces exemples) pour le faire. Mais de tels programmes sont souvent très complexes et peuvent produire des résultats inattendus. C'est pourquoi vous devriez tout de même suivre ces exemples, car ils vous donneront un aperçu majeur de la façon dont les animations devraient être gérées et fusionnées.

Concaténation sérielle (dans le temps)

Concaténer deux animations GIF de sorte qu'une séquence en suive une autre dans le temps est simple avec IM. Il suffit fondamentalement de les lister sur la ligne de commande et elles se suivront. Mais ce n'est peut-être pas aussi facile qu'il y paraît. Par exemple, après quelques recherches sur le web, j'ai trouvé (enfin, volé et fortement modifié pour cet exemple) quelques animations de lettres en train d'être tracées. Maintenant, j'aimerais joindre ces images de sorte que lorsqu'une animation se termine, la suivante commence, comme si quelqu'un écrivait le mot « OK ». Voici les lettres, la « séquence d'animation » et les détails des internes de ces deux animations. | |

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

| [IM Text]

| | [IM Text]

[IM Output]
[IM Output]
Ces séquences démarrent avec un canevas vide puis ajoutent et modifient lentement des pixels sur ce canevas. Elles ne suppriment, n'effacent ni ne rendent transparent aucun pixel ajouté par les images précédentes. Pour nos besoins, cependant, peu importe qu'elles le fassent ou non, car cela aura peu d'incidence sur les résultats. Le nombre d'images de l'animation n'aura pas non plus d'incidence sur cette opération. Ce qu'il est important de connaître, ce sont les timings des images, car cela pourrait poser des problèmes. Remarquez en particulier le délai temporisé sur la première image, ou dans ce cas la dernière. Cette technique est très courante, donnant au spectateur le temps de voir le résultat final avant que l'animation ne s'efface et ne recommence. Ce sont ces délais et ces images qui nous poseront des problèmes lors des concaténations dans le temps. Remarquez aussi que l'animation « k » a un léger délai au milieu de la séquence d'animation. Ce délai représente la fin du premier coup de pinceau dans cette animation et le deuxième coup de pinceau. Ce délai devra aussi être préservé, ce qui signifie que nous ne pouvons pas simplement fixer toutes les séquences temporelles de l'animation à une valeur constante. Une chose qui n'est pas montrée ci-dessus, c'est que la première image des deux animations est en réalité un canevas vierge. Nous voudrons probablement jeter ce canevas sur la seconde animation comme une perte de temps inutile, bien qu'il faille le conserver sur la première animation comme délai de départ. Maintenant que nous avons examiné les deux animations, essayons de les joindre pour que l'une suive l'autre dans le temps. Concaténer des animations dans le temps est en réalité une opération très simple, il suffit de concaténer les deux images animées sur la ligne de commande. Essayons donc simplement cela... |

    magick script_o.gif script_k.gif   script_ok_try1.gif

[IM Output]
Eh bien, le résultat était loin d'être parfait. Les lettres sont tracées dans le bon ordre, mais l'une par-dessus l'autre ! Non seulement cela, mais comme la première animation « o » est plus étroite (40 pixels) que la seconde animation « k » (53 pixels), la toute dernière partie de la lettre finale « k » se retrouve rognée par cette taille de canevas d'encadrement plus petite. La position de la seconde animation peut être déplacée à l'aide d'un repage relatif, comme montré ci-dessus. Cette méthode de repositionnement préservera tout décalage existant éventuellement présent dans cette animation, elle les déplacera simplement tous comme un seul groupe lié. Dans ce cas, presque toutes les images ont un décalage existant, car il s'agit d'une animation fortement optimisée. Pour accommoder cette position décalée et éviter de « rogner » la seconde animation, nous devons aussi agrandir la taille du canevas pour toute l'animation. Changer la taille du canevas avant de lire la première animation ou image agrandira la zone de canevas dans laquelle l'animation se déroule, et empêchera le « K » d'être rogné. |

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

[IM Output]
Le résultat est une nette amélioration. Cependant, les délais entre le tracé des lettres sont désormais nettement perceptibles. Ce que nous voulons, c'est un délai bien plus court pour la dernière image de la première animation « O ». Juste assez long pour donner l'impression que l'artiste invisible repositionne le stylo. Pour cela, nous faisons une copie de cette dernière image de la première animation, puis nous changeons le délai de cette seule image à l'aide de l'opérateur « [-set](https://imagemagick.org/command-line-options/#set) ». Nous réintégrons ensuite cette image dans la séquence d'images en supprimant l'image d'origine non modifiée. De plus, comme nous avons maintenant fixé un bon délai entre le tracé des lettres, le canevas vierge initial (représentant simplement un délai de départ initial) de la seconde animation est désormais superflu, nous pouvons donc simplement supprimer cette image, sans problème. Si cette image contenait réellement une partie de l'image, il nous faudrait peut-être ajuster son délai, au lieu de la supprimer. |

    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]
Et notre concaténation sérielle, ou dans le temps, de deux animations est terminée, et tous les petits problèmes associés à ces deux animations particulières sont corrigés. Remarquez qu'à aucun moment je n'ai essayé de modifier globalement TOUTES les images individuelles, ni leurs délais de timing. Autrement dit, j'ai préservé autant que possible des animations d'origine tout en atteignant mon objectif. C'est important, car toutes les animations n'utilisent pas un délai de timing constant entre les images, et changer cela peut rendre une animation très laide.

Concaténation côte à côte (synchronisée dans le temps)

Supposons que vous vouliez que les deux animations soient concaténées côte à côte, mais que les deux parties de l'animation s'animent en même temps. Ce n'est pas si facile, car vous devez concaténer (ou composer ensemble) chaque paire d'images des deux animations, de sorte que l'animation fonctionne aussi de concert. Le vrai problème pour faire cela, c'est que la ligne de commande IM ne travaille qu'avec une seule séquence d'images. Elle n'a pas le luxe d'une API où vous pouvez conserver deux séquences d'images distinctes, pour les parcourir et les concaténer dans une troisième. Je peux penser à trois techniques de base pour réaliser cette concaténation. Avant de commencer, cependant, vous devriez d'abord étudier les deux animations, pour vérifier les séquences temporelles et d'autres détails de l'animation. Le script « [gif2anim](../static/img/scripts/gif2anim) » est bon pour cela, et le fichier « .anim » généré peut être utile plus tard. | |

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

| [IM Text]

| | [IM Text]

[left]
[right]
Si vous regardez les résumés d'informations, vous verrez que les deux animations ont exactement le même nombre d'images, et presque exactement la même séquence temporelle. C'est la similarité des timings qui est importante ici, et vous pouvez dire que les animations sont déjà « synchronisées dans le temps ». Cependant, bien que les timings soient corrects, les animations sont optimisées par image, plutôt qu'entièrement fusionnées. Mais la hauteur de la zone de canevas est la même, ce qui rend la concaténation des deux images côte à côte réalisable. En réalité, cette animation avait été mal « découpée » (voir découper une animation dans la série d'exemples suivante), si bien que l'animation du « chat » avait été coupée en deux, et l'original perdu. D'autres modifications ont entraîné une très légère différence de timing, qui n'a fait que rendre la division plus évidente. C'était un problème qui m'avait été présenté par gmabrys dans une discussion sur les forums IM, bien que le problème réel qu'il avait donné soit bien, bien pire. [left][right] Or, les navigateurs animent généralement chacune des images GIF distinctes, sans aucune synchronisation. Ainsi, les deux animations peuvent se désynchroniser l'une de l'autre, produisant un « chat » qui semble avoir été victime d'un massacre à la tronçonneuse. Vous pouvez peut-être voir cet effet à droite, où j'ai placé deux animations côte à côte sur la page du navigateur, surtout si vous êtes sur un serveur distant via des liens lents. Maintenant, tentons de les concaténer en une seule image animée correctement synchronisée.

Concaténer des fichiers séparés

La façon la plus simple est de simplement fusionner les deux animations et de les séparer en fichiers image distincts, une image par fichier. Les images distinctes peuvent alors être concaténées ensemble (ou les images modifiées autrement) comme il convient. Une fois terminé, les nouvelles images peuvent alors servir à reconstruire l'animation. Cela vous oblige toutefois à sauvegarder beaucoup d'informations supplémentaires sur l'animation qui pourraient très facilement être perdues durant ce traitement. |

  # Séparer les animations en images fusionnées (plus un fichier ".anim")
  gif2anim -c bag_left.gif
  gif2anim -c bag_right.gif

  # Concaténer ensemble les images séparées
  for i in `seq -f '%03g' 1 11`; do \
    magick bag_left_$i.gif bag_right_$i.gif +append bag_append_$i.gif; \
  done

  # Reconstruire l'animation (en utilisant l'un des fichiers ".anim")
  anim2gif -c -b bag_append  bag_left.anim

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

[IM Output]
Comme vous pouvez le voir, c'est un processus assez laborieux, générant de nombreuses images temporaires individuelles, et nécessitant donc pas mal de nettoyage une fois terminé. Bien sûr, si vous déboguez ce qui précède, les fichiers temporaires individuels facilitent la compréhension de ce qui ne va pas dans votre traitement. Cela montre aussi la puissance du script « [gif2anim](../static/img/scripts/gif2anim) » et de son inverse le script « [anim2gif](../static/img/scripts/anim2gif) » pour séparer et sauvegarder les métadonnées de l'animation, puis reconstruire ensuite les animations GIF. Fondamentalement, cela vous permet de préserver les timings d'origine des animations, sans avoir à les coder directement dans votre script. L'image finale doit tout de même être réoptimisée, bien que dans ce cas vous obtiendrez très peu d'optimisation, car beaucoup de choses se produisent simultanément dans toute l'animation entre chacune des images.

Composition en couches

Une meilleure technique consiste à superposer les animations à l'aide d'une composition de couches de liste multi-images. Cela implique juste d'agrandir un ensemble d'images, et de superposer l'autre ensemble pour les joindre. En fait, c'est ce que fait l'opérateur « [-append](https://imagemagick.org/command-line-options/#append) » normal en interne, donc ce n'est pas si différent. Ici, je dis simplement à IM quelle taille donner au canevas, puis je le remplis à l'aide de « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) ». Je superpose ensuite l'autre animation fusionnée avec un décalage approprié. |

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

[IM Output]
Bien sûr, la technique ci-dessus signifie que j'avais besoin de connaître la taille exacte que ferait l'animation finale, ainsi que le décalage nécessaire pour l'animation superposée. Mais le processus est rapide, fonctionne très bien, et une commande scriptée peut pré-lire les images pour déterminer ces informations. Pour créer une méthode de concaténation d'animations plus universelle, nous devons faire quelques manipulations d'images astucieuses pour déterminer automatiquement la taille et le décalage finaux de la concaténation. Pour faire cela sans pré-lire l'animation, il faut faire quelques contorsions, mais une concaténation générale d'animation en une seule commande est possible. Nous devons d'abord concaténer la première image fusionnée de chaque animation pour créer un canevas de la bonne taille, puis celui-ci est effacé. La première animation est fusionnée et superposée dans la moitié gauche de ce canevas, puis la seconde animation est fusionnée et superposée avec une « -gravity East » pour la placer dans la moitié la plus à droite du canevas préparé, afin d'éviter le besoin d'un décalage. |

  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]
Et voilà une technique générale pour concaténer ensemble deux animations synchronisées dans le temps.

Double concaténation, concaténation - ou concaténation de polices animées

Avant d'en finir avec la concaténation d'animations, il y a une autre technique que j'aimerais vous montrer. Cette technique peut concaténer plusieurs animations en même temps, mais au prix de la perte de toutes les informations de timing qui étaient présentes. Souvent (mais pas toujours), ces timings ne représentent pas une grande perte. Fondamentalement, nous concaténons verticalement toutes les images de chaque animation en une seule image, puis nous concaténons ou superposons toute l'animation comme deux simples images. C'est un peu comme scotcher ensemble deux bandes de film côte à côte pour produire une bande de film plus large. |

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

[IM Output]
Cela n'a nécessité aucun fichier temporaire, mais comme je l'ai mentionné au début, tous les délais temporels d'origine ont été perdus. Pour cet exemple, j'ai simplement fixé tous les délais de l'animation à une valeur constante, produisant un résultat raisonnable, quoique différent. De plus, pour reconstruire l'animation, nous devions connaître la hauteur d'image de l'animation d'origine, afin de diviser correctement (rognage en tuiles) la « bande de film » élargie. Bien qu'il soit possible de récupérer ces timings à l'aide des scripts « [gif2anim](../static/img/scripts/gif2anim) », le faire va en quelque sorte à l'encontre du but de cette méthode, et vous pourriez tout aussi bien utiliser la première technique de concaténation d'animations, en concaténant les images individuelles sous forme de fichiers temporaires. Comme vous concaténez les animations comme de simples images, vous pouvez concaténer toute une série d'animations en même temps (produisant une « bande de film » encore plus large), et c'est ce qui rend cette technique si utile. Par exemple, vous pouvez l'utiliser avec des polices animées qui utilisent toutes les mêmes timings. Bien que j'aie constaté que si beaucoup de polices animées ont le même nombre d'images, elles ont généralement des timings légèrement différents pour chaque lettre afin de désynchroniser les lettres animées (voir Découper une animation pour savoir pourquoi c'est souhaitable). Une enseigne au néon, en revanche, devrait avoir des timings d'animation synchronisés, je vais donc l'utiliser comme exemple...

  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]

Vous pourriez aussi faire quelque chose d'un peu plus élaboré, en ajustant les timings et le nombre de boucles de l'animation résultante.

  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]

Les deux premières lignes créent la partie « toujours allumée » de l'enseigne (première image de chacune des lettres précédemment animées). Après cela, la dernière lettre « en panne » est ajoutée et toute l'animation est doublée à quelques reprises pour produire environ 16 images. Les timings sont réglés pour obtenir l'effet désiré, la première et la dernière image étant affichées pendant une longue période, tandis que le reste des images défile vraiment très vite (« -delay 10 »). En fait, cette animation GIF s'optimise en un fichier bien plus petit que vous ne le penseriez probablement pour le nombre d'images concernées. Fondamentalement, l'optimiseur GIF d'IM a constaté qu'il n'avait besoin de resuperposer l'animation du « O » qu'une image sur deux, et a utilisé un disposal « Previous » pour simplement restaurer le « O » précédemment allumé. L'animation n'est donc qu'environ 50 % plus grande que l'image de base « hello » clignotante non optimisée. Vérifiez par vous-même. Pouvez-vous améliorer l'animation au néon ? La rendre plus réaliste ? C'est dommage que les animations GIF n'aient pas de son.

Découper une animation

Maintenant que nous avons rejoint l'animation, tentons de la découper correctement pour un usage sur des serveurs web, afin que les différentes parties puissent s'animer séparément, sans interférer les unes avec les autres. C'est en réalité raisonnablement difficile, et je ne tenterai pas d'automatiser complètement le processus. Il existe toutefois des outils sur le web qui peuvent le faire. Tout d'abord, nous devons étudier l'animation pour trouver quelles parties de l'animation changent sur toute la durée. Pour cela, nous devons trouver les différences d'une image à la suivante, les additionner toutes dans une carte montrant les zones qui sont animées, par opposition à celles qui restent complètement statiques. C'est délicat. Fondamentalement, une composition alpha multi-images est utilisée pour trouver une image de « [Difference](compose.html#difference) » entre chaque image de l'animation. Ces images de différence en niveaux de gris sont additionnées ensemble, puis les canaux sont séparés et aussi additionnés. Un seuil final rend alors pur blanc tout changement non nul entre n'importe quelle image de l'animation. Le résultat est une image noire avec du blanc partout où l'image a changé, mettant en évidence les zones de changement.

  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]

Nous pouvons maintenant voir que cette animation pourrait être divisée en au moins trois zones : une zone « chat » en haut, un petit « ours » à gauche, et une « aile » qui bat à droite. Toutes avec de simples coupes orthogonales (verticales ou horizontales). Faisons donc simplement cela, avec quelques simples rognages par fenêtre d'affichage de l'animation. |

  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]
Ces trois images peuvent être affichées ensemble par le navigateur sans avoir l'aspect « Massacre à la tronçonneuse au Texas », car à aucun moment une sous-animation ne franchit les frontières d'une autre. Techniquement, vous pouvez faire quelques coupes supplémentaires pour séparer les zones non animées des zones animées, découpant cette animation en environ six zones ou plus, bien que vous ne gagniez pas grand-chose en optimisation à le faire. Tout ce que cela ferait vraiment, c'est compliquer votre page web et créer davantage de fichiers à télécharger pour l'utilisateur. Or, contrairement à l'animation plus grande, ces zones plus petites s'animeront de façon tout à fait indépendante les unes des autres. Nous pouvons même aussi changer les timings de ces simples sous-animations sans nuire au résultat, de manière à les désynchroniser complètement des autres sous-animations. Le résultat est une image animée plus agréable et moins répétitive (voir ci-dessous). Si vous étudiez l'« ours qui rebondit » et l'« aile qui bat », vous constaterez qu'ils forment un simple cycle de deux images qui se répète un certain nombre de fois, pour correspondre au timing du chat qui salue. Nous pouvons donc jeter les répétitions supplémentaires pour simplifier ces animations. De plus, les deux premières images du « chat » sont aussi exactement identiques. Cependant, contrairement à l'« ours » et à l'« aile », vous ne pouvez pas simplement en supprimer une, car chaque image contient des délais temporels pour permettre à l'« ours » et à l'« aile » de s'animer sans que le chat soit présent. Pour supprimer correctement ces images dupliquées, vous devez utiliser la méthode « [RemoveDups](anim_opt.html#removeDups) » de « [-layer](https://imagemagick.org/command-line-options/#layers) » pour localiser et fusionner les timings de telles images dupliquées dans une animation fusionnée. Et voici les optimisations finales, des trois animations séparées avec les changements de timing pour améliorer la désynchronisation globale des sous-animations. J'ai aussi affiché les trois animations côte à côte sur la page, exactement comme elles devraient être affichées. |

  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]
En guise de résumé final : les deux images d'origine (mal découpées) totalisaient [IM Text] octets, ce qui correspond à peu près à la version concaténée. Après avoir correctement découpé l'animation, ce qui permet une bonne optimisation des sous-animations, nous obtenons un total de [IM Text] octets sur trois images. Une assez belle économie.

Découpage d'images à changement distant

En cours de rédaction

Exemple de découpage des mises à jour d'images de « deux objets qui changent et sont éloignés l'un de l'autre », sans faire intervenir la transparence (fond fixe), mais en préservant la synchronisation temporelle entre les parties. Puis répétez avec un fond transparent (nécessitant « OptimizePlus » pour générer les pixels « effacés »). Voir Découper les actions d'image pour l'exemple général.

Fusionner des animations décalées dans le temps

Avant que deux animations puissent être fusionnées pour tourner de façon synchrone, vous devez faire en sorte que toutes les animations utilisent le même nombre d'images, et utilisent le même ensemble de délais temporels. La difficulté de la fusion dépend en réalité du degré de décalage des timings de l'animation. Si les délais temporels sont fondamentalement constants, vous pouvez simplement les ignorer et corriger les timings plus tard. Un exemple où le temps pouvait être ignoré lors de la fusion d'une animation de 2 images avec une animation de 6 images a été donné dans une discussion sur les forums IM. De plus, si la durée totale du cycle est très différente, vous devrez peut-être ajuster les choses pour qu'une animation boucle 2 ou 3 fois afin de remplir la durée du cycle de l'autre animation. Fondamentalement, c'est le timing qui compte.

Probablement quelque chose comme... * + Déterminer et ajuster les animations à une durée de cycle de boucle totale commune * + Fusionner (coalesce) les deux animations pour supprimer toute optimisation d'image. * * Convertir les délais temporels des images en temps écoulé depuis le début de l'animation. * * Dédoubler les images comme il convient pour synchroniser dans le temps. * * Reconvertir le temps écoulé depuis le début en délais temporels des images. * + Superposer les images synchronisées dans le temps et fusionnées comme souhaité. * + Fusionner de façon optimale et supprimer toute image à « délai nul ». * + Réoptimiser la nouvelle animation.

Les parties marquées « * » pourraient être transformées en une nouvelle méthode « [-layer](https://imagemagick.org/command-line-options/#layers) » unique pour synchroniser dans le temps les deux animations ayant des durées de cycle total similaires.

En cours de rédaction

Exemple, décalé dans le temps, mais même durée de cycle...

Par exemple, supposons que vous ayez deux animations de trois images avec des délais temporels de
    10  10  10
    5    5  20

Les deux animations font déjà 30 unités de temps, ce n'est donc pas un problème.

Maintenant, reportez ce qui précède sur l'index temporel où chaque image devrait apparaître...
et montrez la ligne de temps globale à laquelle les images apparaissent...
   0        10    20   |__ REMARQUEZ que les deux animations
   0   5    10         |   se terminent ou bouclent à 30

À partir de cela, vous pouvez voir que vous devez insérer quelques images
supplémentaires pour les faire correspondre.  La première image de la première animation
doit être répétée à l'index de temps 5

0->5  10  20
0  5  10

Et la dernière image de la seconde animation doit aussi être dupliquée à
l'index de temps 20

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

La flèche « -> » ci-dessus signifie que la même image est simplement répétée (dupliquée)
dans l'index de temps suivant. Ce sont en réalité la même image.

Maintenant que les timings des images des deux animations sont identiques, vous pouvez
simplement fusionner (composer) les images ensemble, pour obtenir une animation finale de
4 images.

Les quatre images auront donc des délais temporels de
5  5  10  10
qui totalisent toujours 30 unités de temps (temps global par cycle de boucle)

État actuel du développement....

Bien qu'IM puisse aider à rassembler les informations de délai temporel (essayez l'option '-t' de
"gif2anim") et à construire l'animation. IM ne peut pas effectuer la synchronisation temporelle
nécessaire pour deux animations fusionnées distinctes.  Cela pourrait devenir une option
intégrée spéciale.

Autrement dit, vous devrez déterminer et dédoubler les images d'animation fusionnées
appropriées afin de transformer deux animations décalées dans le temps en deux
animations synchronisées dans le temps.

Une fois les animations synchronisées dans le temps, vous pouvez alors simplement utiliser la
nouvelle méthode "-layers Composite" pour superposer ou fusionner les deux animations
synchronisées dans le temps très facilement.

Tout ce qui précède suppose toutefois que la durée totale de boucle des deux animations
soit au moins à peu près égale, ou pas une préoccupation majeure.


**Solution simplifiée**

Une solution simplifiée et limitée a été [discutée sur les forums IM](https://magick.imagemagick.org/viewtopic.php?p=50325), pour un usage avec des animations à changement rapide (émoticônes).

La solution prend chaque animation et l'étend pour que l'animation ait
une cadence d'images fixe.  Autrement dit, toutes les images sont dupliquées pour que chaque image
soit affichée pendant une durée constante de 6 centisecondes chacune.  Ainsi, une image avec un délai
de 22 cs peut être remplacée par 4 images de 6 cs (24 cs au total).

Après cela, les animations sont encore modifiées pour que les animations courtes soient
bouclées plusieurs fois afin que les deux animations soient finalement de longueur égale.
Autrement dit, les deux animations sont rendues de même longueur globale en termes de temps
et de nombre d'images.

Une fois que les deux animations ont la même cadence d'images et la même longueur, la [composition de couches](#composite) peut être utilisée pour fusionner/superposer les deux
animations, à la bonne position.

Le résultat peut alors être optimisé à l'aide de [Supprimer les images dupliquées](anim_opt.html#removedups) pour supprimer toute image supplémentaire indésirable (avec
les ajustements de timing appropriés et d'autres [optimisations](anim_opt.html#intro) appliquées avant l'enregistrement.

Cette méthode consistant à avoir toutes vos animations composantes sous une forme
à longueur d'image fixe est particulièrement adaptée aux bibliothèques d'animations.


-----
Autre exemple à créer....
  * Superposer deux animations mobiles de même durée en une seule animation
    (papillons dansants, atomes en orbite, ou oiseaux ?)
    Cela devrait être une composition de couches directe.

  * Superposer une animation mobile sur un fond fixe.
    (déplacer l'animation linéairement dans le temps)

  * Superposer deux animations avec des nombres d'images différents mais des délais temporels
    constants (voir [discussion sur les forums IM](https://magick.imagemagick.org/viewtopic.php?t=12573)).

  * Superposer deux animations décalées dans le temps (comme décrit ci-dessus)

  * Superposer une figure animée simple sur un fond animé.
    (fusion d'animation complète)