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

ImageMagick Examples -- Optimisation des animations

ImageMagick Examples : préface et index
Introduction à l'optimisation
Optimiseur GIF polyvalent d'ImageMagick
Optimisation des trames

Introduction à l'optimisation des animations

Optimiser une animation n'est pas chose facile, surtout une animation GIF, qui souffre de restrictions de couleurs, offre le choix entre différentes techniques de suppression de trame et permet de superposer de plus petites « sous-trames » d'une trame à la suivante. Pour optimiser une animation, il convient de procéder dans l'ordre suivant.

Ce n'est cependant pas dans cet ordre que nous examinerons ces techniques d'optimisation. Pour les animations GIF, l'optimisation des trames est la technique d'optimisation la plus fondamentale, et celle où les gains sont les plus importants. C'est pourquoi nous la traiterons en premier. L'aspect de l'optimisation qui pose sans doute le plus de difficultés aux utilisateurs est celui des optimisations des couleurs, dues aux limitations de couleurs des animations GIF. L'un de ces aspects, la table de couleurs globale unique, doit être réalisé en toute dernière étape avant l'enregistrement au format GIF, sous peine de perdre l'effet des opérateurs lors de l'enregistrement final du fichier GIF.


Optimiseur GIF polyvalent d'ImageMagick

La méthode « **Optimize** » de « [-layers](https://imagemagick.org/command-line-options/#layers) » met en œuvre plusieurs des techniques détaillées ci-dessous pour tenter d'optimiser une animation GIF en une seule étape raisonnable. Actuellement, cette option équivaut à (dans l'ordre)…

À ce stade, vous pouvez enregistrer immédiatement l'animation GIF. Ce sont des étapes d'optimisation raisonnablement sûres, applicables à la plupart des séquences d'animation, sans toutefois aucune garantie d'aboutir à une animation GIF plus petite. C'est particulièrement vrai pour une séquence vidéo brute, où une optimisation de la transparence dégradera généralement le taux de compression LZW. Cependant, pour la plupart des animations GIF, qui mettent en jeu des images de type dessin animé, l'opérateur « Optimize » devrait produire une animation bien optimisée. L'opérateur est néanmoins encore en développement et devrait à l'avenir inclure aussi d'autres étapes d'optimisation standard, telles que…

  • Un seuillage à 50 % du canal alpha, exactement comme IM le fait normalement lors de l'enregistrement au format GIF, afin de supprimer les pixels semi-transparents. Vous pouvez toujours gérer vous-même la semi-transparence au préalable pour outrepasser ce comportement, si vous le souhaitez. Voir Transparence booléenne du GIF pour plus de détails.
  • Une technique d'optimisation des couleurs. Sa nature exacte reste à définir et pourrait être choisie en fonction de l'animation et du nombre de couleurs concernées. Suggestions bienvenues.
  • Une table de couleurs globale unique, soit une opération « [+map](https://imagemagick.org/command-line-options/#map) ».

Autrement dit, on espère qu'« Optimize » deviendra à terme l'optimiseur d'animations GIF générique d'IM, d'usage rapide et simple pour les utilisateurs d'IM. D'ici là, soyez prudent dans son utilisation, en particulier dans les scripts, car il évoluera. Bien entendu, de nombreuses étapes d'optimisation peuvent ne pas valoir l'effort pour une animation donnée. Cette option deviendra aussi probablement assez lente. Tel est le plan, et l'objectif que visait cette section des IM Examples.


Optimisations des trames

L'optimisation des trames repose sur la superposition d'une sous-image plus petite plutôt que sur la superposition complète de l'image entière. Cela produit évidemment un nombre de pixels moindre, donc un fichier plus petit sur le disque et à transmettre sur le réseau. De plus, superposer une trame plus petite signifie que l'ordinateur client a moins de travail pour modifier les pixels à l'écran. Toutefois, le format GIF propose différentes méthodes de suppression pour gérer la dernière trame affichée, ce qui peut entraîner des superpositions de tailles variables. Non seulement cela, mais il est possible de découper les superpositions en plusieurs parties, ou actions de mise à jour, pour aboutir à une animation plus complexe mais mieux optimisée. En raison de la complexité de l'optimisation des trames, toute optimisation de trame existante est en général toujours supprimée d'abord au moyen de l'opération « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) ». Voir les exemples de Coalesce. Naturellement, cela supprime aussi toute optimisation manuelle qui aurait pu exister, une certaine prudence est donc conseillée.

Optimisation de trame élémentaire

La méthode « [-deconstruct](https://imagemagick.org/command-line-options/#deconstruct) » produit une optimisation de trame élémentaire pour une animation GIF. Cependant, comme l'ont montré les exemples de Deconstruct de la section précédente, cet opérateur ne fonctionne pas avec toutes les animations GIF lorsque des pixels transparents entrent en jeu. Plus précisément, lorsqu'une animation efface un pixel coloré vers la transparence. Autrement dit, il ne fonctionne qu'avec les animations par superposition. La méthode « **OptimizeFrame** » de « [-layers](https://imagemagick.org/command-line-options/#layers) » est conçue comme un optimiseur de trames GIF, qui tente de trouver les plus petites images de superposition de sous-trames, en recourant à n'importe quelle méthode de suppression GIF. Le résultat est généralement une animation à suppression mixte, même si elle générera souvent aussi une animation à trames effacées ou une animation par superposition pure, si cela s'avère être la meilleure solution pour l'animation en question. Rappelez-vous que l'animation en entrée doit être une « animation coalescée », c'est-à-dire constituée d'une suite de trames d'image complètes, toutes de même taille, sans aucun décalage de canevas. Bien entendu, toute méthode de suppression existante dans une animation coalescée est totalement sans objet et sera ignorée par la méthode « OptimizeFrame ». Par exemple, essayons cela avec une animation à suppression Previous, créée dans la section précédente. | |

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

[IM Output]
[IM Output]
[IM Output]
Comme vous pouvez le constater, « [-layers](https://imagemagick.org/command-line-options/#layers) OptimizeFrame » a correctement ramené notre animation à sa forme optimisée d'origine, en utilisant l'suppression Previous. Cette optimisation fonctionne même correctement pour les animations à suppression Background, plus délicates à traiter… | |

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

[IM Output]
[IM Output]
L'animation est parfaitement optimisée en trames au moyen de l'suppression Background. Cet opérateur fonctionne correctement pour toutes les animations GIF et renvoie en général la meilleure « suppression et optimisation de trame » simple possible.
Voici maintenant quelques mauvaises nouvelles concernant tout type d'optimisation de trame simple, telle que celle fournie par IM… Si « [OptimizeFrame](#optframe) » renvoie la meilleure optimisation de trame qu'IM puisse déterminer pour une animation donnée, il existe un certain nombre de cas particuliers où il ne s'en sort pas bien. Cela inclut notamment…

  • Les animations où l'effacement de pixels (retour à la transparence) est nécessaire, mais où les superpositions de trames sont trop grandes pour effacer efficacement les petites zones de pixels à effacer (voir l'animation du trou mobile ci-dessous).
  • Les animations comportant deux petites zones de changement ou plus, éloignées l'une de l'autre. Elles sont en réalité assez courantes et affreuses à optimiser en trames. (Voir Fractionnement des mises à jour de trame ci-dessous)
  • Les animations dont l'arrière-plan très complexe reste statique pendant de longues périodes (plus de 3 trames), puis change légèrement avant de rester statique pendant une nouvelle longue période, et ainsi de suite… Ou un arrière-plan statique qui se trouve fortement masqué pendant un très court instant. Il peut être quasi impossible pour tout algorithme informatique de déterminer la « meilleure » optimisation de trame dans une situation aussi complexe (autrement dit : qu'est-ce qui doit être considéré comme un arrière-plan statique ?). Seuls les humains, avec leur appréhension intuitive de ce qu'ils voient, peuvent générer une bonne séquence de superposition de trames optimale dans ces cas-là.

Des exemples d'animations difficiles à optimiser sont recherchés, merci de contribuer. Si vous trouvez un exemple d'animation pour laquelle IM échoue à produire une bonne optimisation, envoyez-le-moi par courriel pour étude complémentaire. C'est ainsi que de nouvelles techniques et d'éventuelles solutions automatiques peuvent être mises au point. Je publierai bien entendu votre nom en tant que contributeur.

Aucune superposition de pixels - image répétée une trame sur deux

[animation] Il arrive que la meilleure optimisation d'une image consiste à ne superposer aucun pixel ! Par exemple, voici à droite une animation simple, fournie par nixscripter. En regardant ses trames, on voit qu'elle n'est guère optimisée. Mais remarquez qu'une trame sur deux de l'animation est simplement répétée.

  gif_anim_montage paddleball.gif paddleball_frames.gif

[IM Output]

Après optimisation des trames, on obtient une séquence de suppression GIF très particulière. | |

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

[IM Output]
[IM Output]
Ce qui se passe, c'est qu'au lieu de superposer la trame d'origine, IM a choisi de restaurer la première image en utilisant une suppression GIF « Previous ». Comme cette trame restaurée est laissée telle quelle, aucun pixel n'est modifié. La superposition de sous-trame se réduit donc à rien. Malheureusement, ni IM ni le format GIF ne permettent d'avoir une image de taille nulle, une image minimale spéciale d'un seul pixel transparent est donc utilisée à la place. Cette image est connue sous le nom d'image manquante, car elle est aussi largement employée lorsque « [-crop](https://imagemagick.org/command-line-options/#crop) » « manque » les données réelles de l'image, produisant le même résultat. Cette image, en effet, ne préserve que les métadonnées de la trame, telles que : la méthode de suppression, le délai temporel et le nombre d'itérations de boucle. C'est donc une partie essentielle de l'animation, même si elle est « vide ». Ainsi, en superposant un unique pixel transparent minimal, IM a économisé une énorme quantité d'espace (et de temps) dans cette animation.

Animation du trou mobile - difficile à optimiser en trames

Voici un cas extrême d'animation GIF qui ne s'optimise pas bien en trames avec la moindre méthode d'optimisation habituelle. Cette animation se compose essentiellement d'une simple image d'arrière-plan inchangée, mais percée d'un « trou » transparent qui change de position d'une trame à l'autre. Pour la créer, je dois produire une séquence d'images coalescée, où je découpe un trou dans une image d'arrière-plan fixe, à l'aide de la composition alpha en couches. J'ai aussi utilisé un commutateur « [+antialias](https://imagemagick.org/command-line-options/#antialias) » pour garantir que seules quatre couleurs soient employées : trois bleus et la transparence. Ainsi, nous n'avons pas à nous soucier des problèmes d'optimisation des couleurs. | |

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

[IM Output]
[IM Output]
Comme vous pouvez le voir, l'animation fonctionne : un « trou » rond laisse apparaître la couleur d'arrière-plan de cette page, produisant un fichier d'animation de [IM Text] octets. Essayons donc une optimisation de trame directe pour cette animation. | |

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

[IM Output]
[IM Output]
Un instant, rien ne s'est passé ! La meilleure optimisation qu'IM ait pu obtenir a été aucun changement du tout ! La version coalescée ci-dessus de cette animation est-elle vraiment la plus optimale ? Eh bien, pour l'animation en l'état… Oui, c'est réellement la meilleure optimisation simple réalisable par pure optimisation de suppression de trame ! Ce n'est pas brillant. Le problème est que pour qu'une animation GIF « efface » ou « gomme » les pixels dessinés par les trames précédentes, elle doit recourir à une méthode de suppression « Background ». Bien que, dans certaines situations particulières, une méthode de suppression « Previous » puisse aussi convenir. Cependant, la suppression « Background » ne peut effacer que les zones qui viennent d'être superposées. Comme la première trame était une superposition complète de l'image entière, c'est l'image entière qui sera effacée. Alors même que seule une petite portion de l'animation a besoin que ses pixels soient effacés. En conséquence, la deuxième trame doit être entièrement superposée, alors même que l'essentiel de cette trame venait tout juste d'être affiché ! Cette situation inextricable se poursuit tout au long du reste de l'animation, sans produire la moindre optimisation de trame élémentaire. J'avais bien dit que cette animation serait difficile à optimiser en trames.

Doublement de trame - une méthode pour optimiser les « trous » en trames

Tout n'est cependant pas perdu. En ajoutant quelques trames supplémentaires à l'animation, vous pouvez donner à la méthode « [OptimizeFrame](#optframe) » une marge de manœuvre pour mieux exploiter les méthodes de suppression GIF disponibles. Ici, par exemple, nous ajoutons une trame supplémentaire en doublant la première image, mais en lui attribuant un délai nul afin de ne pas modifier les timings globaux de l'animation. | |

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

[IM Output]
[IM Output]
En doublant la première trame, l'animation est passée de [IM Text] octets à [IM Text] octets. Ainsi, bien que l'animation compte désormais cinq trames, sa taille globale est nettement moindre, en raison de la réduction massive de la taille des superpositions d'images de sous-trames. Le doublement sépare essentiellement la fonction d'effacement de pixels de la méthode de suppression de la fonction de superposition de pixels assurée par la trame suivante. L'suppression et la superposition sont toutes deux effectuées dans le cadre d'une même mise à jour de trame par les programmes d'animation GIF, aucune perte de vitesse ni de qualité ne devrait donc être perceptible. C'est une technique complexe et subtile, rarement rencontrée ou comprise des concepteurs d'animations GIF ou des programmes d'optimisation GIF, mais ses avantages valent bien la peine lorsqu'elle est nécessaire. Cependant, la réduction de la taille des images de sous-trames ne dure qu'un court instant, car les trames ultérieures doivent elles aussi effacer des pixels pour la trame suivante, si bien qu'elles redeviennent grandes afin de continuer à effacer les pixels ultérieurs. Autrement dit, parce que l'effacement de pixels aboutit toujours à des trames plus grandes, jamais plus petites. Essayons donc de doubler toutes les trames (sauf la dernière, qui n'a jamais besoin d'être doublée) pour voir comment cela influe sur l'image finale… | |

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

[IM Output]
[IM Output]
Comme vous pouvez le voir, bien que nous ayons presque deux fois plus de trames, toutes les tailles d'image sont bien plus petites, produisant une animation de [IM Text] octets, un résultat plus petit, mais loin d'être une économie aussi importante que le premier doublement d'une seule trame réalisé. Pour que vous puissiez suivre ce qui se passe, la trame « [Background](anim_basics.html#background) » est un duplicata exact de la trame précédente, sans changement de ce qui est affiché. Toutefois, elle définit la zone de l'animation à effacer avant que l'image de la trame suivante soit superposée. La trame « [None](anim_basics.html#none) » suivante remplit alors les pixels à modifier, ainsi que les pixels que la suppression des trames précédentes a également effacés. Dans l'animation ci-dessus, cela désigne les pixels nécessaires à la forme du nouveau trou, ainsi que les pixels utilisés pour combler le « trou » précédent. Le résultat est plus petit, mais loin de l'être autant, car ajouter des trames supplémentaires a son propre coût. Au moins, chacune des trames ajoutées ne possède pas sa propre table de couleurs, sans quoi cette animation serait en réalité devenue plus grande, à cause de la taille des tables de couleurs supplémentaires !

Layer Optimize Plus - Optimisation automatique par doublement de trame

J'ai le plaisir d'annoncer que, depuis la version 6.2.7, IM peut désormais réaliser automatiquement l'optimisation par doublement de trame, dans le cadre de son traitement normal d'optimisation des trames. Cependant, comme ajouter des trames pour réduire la taille d'une animation est une démarche si radicale, elle a reçu sa propre méthode « [-layers](https://imagemagick.org/command-line-options/#layers) » distincte, « **OptimizePlus** ». Par exemple, demandons à IM de réaliser l'optimisation par doublement de trame… | |

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

[IM Output]
[IM Output]
Autrement dit, IM vous a donné le même résultat que notre exemple précédent de doublement de trame. Le fichier GIF fait donc toujours [IM Text] octets. Cependant, « OptimizePlus » ne double une trame que si le nombre de pixels des trames courante et suivante de l'animation résultante (3 trames) diminue, on peut donc laisser IM décider s'il faut doubler ou non les trames. Comme la méthode « [OptimizePlus](#optimizeplus) » de « [-layers](https://imagemagick.org/command-line-options/#layers) » ajoute des trames supplémentaires en créant une animation GIF optimisée en trames, elle supprime aussi les trames inutiles ou superflues qui n'apportent aucun changement à l'animation finale (en fusionnant les délais comme il convient). Autrement dit, elle réalise aussi automatiquement un « [RemoveDups](#removedups) » (voir ci-après). La méthode « [OptimizeFrame](#optframe) » ne le fait pas.

Suppression des trames en double - fusion des images en double consécutives

Malheureusement, si vous « coalescez » cette animation, vous récupérerez aussi toutes les trames supplémentaires ajoutées ci-dessus.

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

[IM Output]

Pour vous permettre de supprimer ces trames en double inutiles d'une animation coalescée, une méthode « **RemoveDups** » est proposée. Elle compare chaque trame à la trame suivante de l'animation et supprime la première trame si elles sont identiques (avec une similarité de couleur fixée par le facteur de flou (Fuzz) courant). Par ailleurs, pour garantir qu'aucun timing de l'animation ne soit perdu, les délais temporels des deux trames sont également fusionnés. Par exemple…

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

[IM Output]

Et nous retrouvons maintenant la forme coalescée d'origine de l'animation. Pour une autre méthode de suppression des trames supplémentaires, voir la méthode « [RemoveZero](#removezero) » ci-dessous.

Fractionnement des mises à jour de trame - mettre à jour séparément deux changements éloignés

Comme vous l'avez vu avec le doublement de trame, en séparant l'« effacement des pixels » de la superposition des nouveaux pixels, nous pouvons réduire la taille globale d'une superposition d'une seule trame. Cette animation produit néanmoins encore de très grandes superpositions, constituées pour l'essentiel de pixels qui ne changent en réalité pas d'une trame à l'autre. Autrement dit, la trame de superposition principale ne met à jour que deux zones assez petites et assez éloignées l'une de l'autre, tout en produisant une seule grande image de superposition. Plutôt que de tenter de mettre à jour les deux changements simultanément, en incluant aussi tous les pixels inchangés situés entre les deux zones, nous mettons plutôt à jour chaque zone séparément. Autrement dit, nous fractionnons la mise à jour de trame en deux phases, une pour chacune des zones distinctes qui ont changé. Dans ce cas, nous pouvons d'abord combler le trou, puis créer le nouveau trou comme mise à jour distincte. L'ordre des deux changements distincts importe peu (hormis d'éventuelles considérations de suppression), mais vous devriez tâcher d'être logique à ce sujet. Il se peut aussi qu'un changement soit plus facile à créer qu'un autre. Par exemple, ici, j'insère des trames supplémentaires pour combler l'ancien trou comme mise à jour distincte du « creusement » du nouveau trou. C'est la trame intermédiaire la plus facile à générer, ainsi que l'ordre d'actions le plus logique. Bien entendu, il est inutile de le faire pour la dernière trame, car cette trame est simplement jetée avant que l'animation ne reboucle. | |

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

[IM Output]
[IM Output]
Rappelez-vous que la trame intermédiaire ajoutée est différente des trames voisines affichées à l'utilisateur (celles dont le délai temporel est non nul). Ce n'est pas un simple « doublement de trame », mais la séparation de deux petits changements éloignés. Cet ajout de trames intermédiaires n'est pas une étape simple qui pourrait être automatisée. Bien qu'il soit possible qu'une heuristique astucieuse puisse être mise au point pour générer ces trames intermédiaires, il n'est pas toujours évident de savoir ce qu'il faut faire, ni même s'il faut le faire. Si vous voulez tenter de mettre au point une telle heuristique, écrivez-moi. Essayons donc une optimisation de trame standard après avoir ajouté ces trames supplémentaires… | |

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

[IM Output]
[IM Output]
L'ajout de ces « trames intermédiaires à délai nul » permet à cette animation de mieux s'optimiser en trames que l'animation non optimisée d'origine, produisant une animation de [IM Text] octets. Cependant, pour ce cas précis, ce n'est pas aussi bon que d'utiliser une technique de doublement de trame automatisée (voir la méthode « OptimizePlus » de layers ci-dessus). Toutefois, ajouter des « trames intermédiaires à délai nul » ne vous empêche pas d'appliquer aussi cette technique de « doublement de trame »… | |

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

[IM Output]
[IM Output]
Cette animation comporte désormais deux « trames intermédiaires à délai nul » supplémentaires par mise à jour de trame. La première comble l'ancien trou, la seconde efface une zone qui contiendra des pixels transparents, avant que les pixels qui n'auraient pas dû être effacés soient finalement restaurés. Le résultat est l'optimisation de trame la plus optimale possible pour cette animation problématique précise, aboutissant à [IM Text] octets pour la taille du fichier final. Autrement dit, notre animation de 4 trames a été rendue plus petite en ajoutant 6 trames supplémentaires à délai temporel nul ! Plus du double du nombre de trames initial. Étrange mais vrai ! Bien entendu, il serait aussi appréciable que les programmes d'animation GIF reconnaissent réellement les trames intermédiaires à délai nul pour ce qu'elles sont, à savoir des mises à jour intermédiaires entre les vraies trames de l'animation. Mais même ainsi, lorsque les mises à jour sont très éloignées et très petites, la légère pause causée par les trames supplémentaires est rarement visible.
Bien entendu, si les deux parties séparées de l'animation ne sont en réalité pas liées, elles n'ont pas besoin d'être synchronisées dans le temps. Une autre solution consiste, au lieu d'ajouter des trames supplémentaires, à scinder l'animation en deux animations totalement distinctes que vous pouvez afficher ensemble sur une page web. Voir Scinder une animation. Cette animation particulière ne peut toutefois pas être scindée en animations distinctes disjointes dans le temps. Premièrement, les changements éloignés doivent être synchronisés dans le temps. Deuxièmement, les quatre zones qui changent se chevauchent à la fois horizontalement et verticalement. Cela signifie qu'un simple « tableau » HTML ne peut pas recombiner les sous-animations en un tout complet, sans une astuce CSS quelconque. Pouvez-vous me prouver le contraire ? FUTURE : référence à un meilleur exemple d'animation de « deux objets éloignés », dans « Gestion des animations », mettant en jeu par exemple deux objets se déplaçant séparément.

Suppression des trames à délai nul - supprimer les mises à jour intermédiaires

Bien entendu, il arrive que ces trames intermédiaires ajoutées ne vous intéressent pas ou que vous souhaitiez les retirer d'une animation, ne conservant que les trames qui seront réellement montrées à un utilisateur pendant une certaine durée. Vous ne pouvez pas simplement coalescer l'animation et utiliser la méthode « [RemoveDups](#removedups) », car toutes les « trames intermédiaires » ne ressemblent pas aux trames voisines et ne sont donc pas des doublons. Cependant, comme ce type de trame a un délai temporel nul, vous pouvez utiliser une autre méthode « [-layers](https://imagemagick.org/command-line-options/#layers) » spéciale, « **RemoveZero** », qui supprime toute trame ayant un délai temporel nul. Cette même méthode supprime aussi les trames ajoutées par les techniques de doublement de trame et « [OptimizePlus](#optimizeplus) ». Par exemple…

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

[IM Output]

Ce qui ramène là encore l'animation à ses seules trames visibles par l'utilisateur, la simplifiant. Bien entendu, après avoir supprimé les trames intermédiaires à délai nul, il est très difficile de les rajouter, car l'information de changement qu'elles contenaient est perdue. Par conséquent, l'animation risque de ne plus très bien s'optimiser en trames ensuite. L'optimisation est après tout l'un des principaux objets de telles trames.

Résultats et synthèse de l'optimisation des trames

Faisons la synthèse de nos optimisations de l'animation du trou mobile…

[IM Text]

Comme vous pouvez le constater, en recourant à un traitement de trames complexe, avec l'aide d'IM et d'une certaine intervention humaine, nous avons pu optimiser en trames l'animation du « trou mobile » à presque la moitié de sa taille d'origine, quoique avec un peu moins du triple du nombre de trames initial. Bien entendu, les résultats peuvent varier grandement d'une animation à l'autre, mais les techniques que nous avons employées pour l'optimisation des trames restent les mêmes. Il suffit d'un peu de soin et d'anticipation, ce en quoi les humains excellent et les ordinateurs sont mauvais. | _Il faut souligner qu'IM ne devrait pas seulement tenir compte du nombre de pixels de l'ensemble de trames actuellement examiné, mais aussi de la taille globale de la trame supplémentaire ajoutée, et peut-être des résultats de compression globaux obtenus, au moment de décider comment optimiser l'image en trames.

D'un autre côté, IM ne considère pas non plus les économies de nombre de pixels susceptibles d'en résulter au-delà des trames directement concernées. Autrement dit, la taille des trames ultérieures peut elle aussi être moindre du fait du doublement de trame ou de la méthode de suppression employée. C'est particulièrement vrai lorsque le choix porte sur l'usage de la méthode « suppression de l'image précédente », qui peut entraîner des réductions substantielles du nombre de pixels plus loin dans la séquence d'animation, plutôt que dès la trame immédiatement suivante. Un bon choix ici nécessite souvent une intervention humaine.

De ce fait, je ne peux offrir aucune garantie qu'IM produira les meilleurs choix d'optimisation pour une animation donnée. Il s'y emploie néanmoins avec application, sans recourir à la récursivité, pour faire ce choix. Autrement dit, en n'utilisant que les décomptes de pixels immédiats pour sa décision.

Un algorithme récursif, qui ferait un choix puis observerait la meilleure taille finale de l'animation résultant de ce choix (y compris des choix récursifs plus loin), pourrait produire une optimisation optimale garantie. Mais il pourrait aussi constituer un opérateur extrêmement lent, et pour une grande animation, la décision finale pourrait prendre des années. Il devrait également inclure les choix d'optimisation de la compression, car ceux-ci pourraient affecter le résultat final. Autrement dit, si un tel algorithme pouvait garantir la meilleure optimisation, il le ferait au prix d'un lourd coût de calcul.

Bien entendu, un être humain doté d'une connaissance intime de ce que l'animation cherche à accomplir fera généralement mieux sur les animations complexes, comme vous l'avez vu ci-dessus avec le fractionnement des mises à jour de trame.

Si vous souhaitez tenter de créer un opérateur d'optimisation GIF récursif, faites-le, je vous en prie. Je vous aiderai de toutes les façons possibles. Il surpasserait à peu près tous les autres programmes d'optimisation GIF du marché. Et la plupart des développeurs d'animations GIF vous seraient sans doute très reconnaissants de vos efforts (financièrement)._
---|---


Gestion de la semi-transparence

Le format de fichier GIF ne permet pas l'usage de pixels semi-transparents (voir Transparence booléenne du GIF). C'est un fait, et avant de pouvoir optimiser correctement une animation, ou même de l'enregistrer au format GIF, vous devez traiter les éventuels pixels semi-transparents présents, d'une manière adaptée à l'animation. Par défaut, si vous ne traitez pas ces pixels, IM applique un seuil de 50 % pour transformer ces pixels en pixels soit totalement transparents, soit totalement opaques. Ce n'est cependant pas forcément la meilleure façon de gérer le problème, en particulier dans les images qui contiennent de grandes zones de pixels semi-transparents, comme les effets d'ombre. Par exemple, je voulais créer une animation de téléportation d'Asgard de Stargate capable de prendre à peu près n'importe quelle sous-image comme objet à téléporter.

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

[IM Output]

J'ai volontairement laissé l'animation au format de fichier interne MIFF: d'IM, car cela garantit que l'image d'origine est préservée sans modification, et j'ai utilisé le format de fichier PNG: pour afficher les trames afin que vous puissiez voir tous les pixels semi-transparents qu'elle contient ! C'est important non seulement pour les animations comportant des pixels semi-transparents, mais aussi pour celles qui comptent beaucoup de couleurs. Une fois la séquence d'images enregistrée en GIF, vos chances de générer une bonne optimisation des couleurs passent de bonnes à difficiles. Bon, j'ai une séquence d'animation. Si je tente de l'enregistrer directement en GIF, IM se contentera de seuiller tous ces pixels semi-transparents. |

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

[IM Output]

[IM Output]

Le résultat ne ressemble vraiment en rien à ce que nous voulions. La gestion par défaut de la transparence à 50 % fait ressembler l'animation à un « œuf » qui rétrécit. Certainement pas ce que je veux obtenir avec cette animation… Si ce type de gestion de la transparence vous convient, voici comment l'appliquer, avant de poursuivre avec vos autres optimisations…

  magick teleport.miff -channel A -threshold 50% +channel \
                 ...poursuivre le traitement ici...       teleport.gif

Un avantage supplémentaire de la méthode manuelle ci-dessus est que vous pouvez contrôler le niveau de seuil. Par exemple « 10% » pour supprimer presque tous les pixels semi-transparents présents, ou « 90% » pour les rendre tous opaques. |

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

[IM Output]

[IM Output]

Mais appliquer un seuil à des animations comme celle-ci n'est pas une bonne solution, car cela gâche vraiment l'effet de transparence que je cherche à obtenir. La meilleure solution d'ensemble pour préserver tous les effets spéciaux de l'animation ci-dessus est simplement d'ajouter un arrière-plan de couleur unie. |

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

[IM Output]

[IM Output]

Cela supprime TOUTE la transparence de l'animation, mais au prix de ne faire fonctionner l'animation que sur une couleur d'arrière-plan précise. En revanche, si vous créez l'animation pour une page web précise, cela peut tout à fait convenir. Notez toutefois que pour les images aux contours nets, l'usage d'un motif de tramage comme celui-ci peut produire un contour « pointillé » sur les bords nets. C'est pourquoi ce n'est pas recommandé dans le cas général. L'autre solution consiste à tenter de générer un motif de pixels transparents et opaques afin de préserver la semi-transparence de l'image. Et pour cela, IM propose une vaste gamme d'options de tramage susceptibles de résoudre ce problème. FUTURE : un lien vers une section, à créer, sur le tramage de la transparence, telle queQuantification et tramage. Notez que la première solution évidente, à savoir un tramage monochrome du canal alpha, n'est pas simple et nécessite probablement une composition multi-images avancée pour être réalisée correctement. Une solution simple consiste à utiliser une technique de tramage ordonné par diffusion de pixels, qui peut être restreinte au seul canal alpha, pour supprimer les pixels semi-transparents. |

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

[IM Output]

[IM Output]

Le résultat est raisonnable, mais ressemble davantage à un objet qui se dissout qu'à un objet qui se téléporte. Utiliser une demi-teinte (Halftone) produira un bien meilleur effet en rendant le motif de transparence plus marqué. |

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

[IM Output]

[IM Output]

Mais pour cette animation précise, j'ai découvert qu'utiliser une carte de tramage conçue par l'utilisateur pour produire des lignes verticales (à partir d'un motif de tramage à lignes horizontales) produit un effet qui rehausse l'animation de téléportation tout en supprimant les pixels semi-transparents. |

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

[IM Output]

[IM Output]

Comme vous pouvez le voir, il existe un bon nombre de possibilités pour gérer la semi-transparence dans une animation GIF.


Optimisation des couleurs

La gestion des pixels semi-transparents n'est que la première limitation du format de fichier GIF. La suivante est une limite de 256 couleurs pour chaque table de couleurs de l'animation. Vous êtes autorisé à avoir une table de couleurs distincte pour chaque trame. Cela signifie qu'une même animation peut comporter plus de 256 couleurs. Toutefois, même cela n'est pas toujours une bonne idée. Si vous voulez simplement un résumé rapide des options d'optimisation des couleurs disponibles, je vous suggère de passer directement aux exemples de conversion Vidéo vers GIF, où les problèmes de couleurs d'une animation sont à leur comble.

Le problème des couleurs du GIF

Les animations GIF en particulier ont des difficultés à gérer les couleurs : d'abord, elles n'autorisent pas les couleurs semi-transparentes, ensuite elles imposent une limite de 256 couleurs par trame, ou une limite globale de 256 couleurs. Enfin, votre meilleure optimisation de trame ne fonctionnera pas très bien à moins que les couleurs employées pour un pixel dans une trame ne correspondent aussi à la même couleur dans la trame suivante, là où cette partie de l'image n'a PAS changé ! Cela peut sembler un problème facile, mais la réduction des couleurs est en soi un domaine extrêmement complexe, qui a nécessité sa propre section complète dans les IM Examples. Les problèmes de couleurs sont d'ailleurs la raison pour laquelle la plupart des animations GIF que l'on trouve sur le World Wide Web sont de type dessin animé, ou d'aspect très médiocre. Surtout si elles ont été redimensionnées à partir d'une version plus grande de l'animation. Le redimensionnement d'animations exigera probablement plus d'efforts d'optimisation des couleurs que le processus de redimensionnement lui-même. Ici, je suppose que vous disposez de la source originale de l'animation. Mais ce n'est pas toujours possible, aussi, si vous optimisez une animation GIF modifiée, une prudence supplémentaire peut être nécessaire. Cependant, si vous avez une animation comportant trop de couleurs, la première chose à retenir est…

N'enregistrez pas directement au format GIF,
utilisez le format de fichier MIFF, OU des images PNG séparées.

Dès que vous enregistrez en GIF, vous perdez la maîtrise de vos efforts d'optimisation des couleurs GIF, et vous vous retrouvez probablement avec une animation GIF d'aspect très médiocre qui ne s'optimisera pas très bien avec les diverses techniques d'optimisation des trames.

Animation de vitesse - une animation avec trop de couleurs

Il nous faut d'abord générer une animation GIF avec un nombre considérable de couleurs, afin de pouvoir vraiment mettre à l'épreuve les problèmes liés à l'optimisation des couleurs. | |

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

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

[IM Output]
[IM Output]
Notez que je n'ai pas enregistré l'animation directement au format GIF, mais dans un fichier au format MIFF, « [speed.miff](../static/img/anim_opt/speed.miff) », au préalable. Cela préserve tous les aspects de l'animation créée (ou modifiée) à l'origine, y compris les métadonnées GIF, les délais de timing, ainsi que toutes les couleurs de l'image sans distorsion. Ce n'est qu'après avoir préservé l'animation originale que j'ai converti directement l'animation d'origine au format GIF. Ainsi, je pouvais montrer ce que le code ci-dessus est censé accomplir, et pourquoi je l'ai appelé « vitesse ». Cela a aussi été fait pour fournir une animation GIF de référence à des fins d'étude et de comparaison ultérieure. Examinons donc divers détails de notre animation d'origine…

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

[IM Text]

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

[IM Text]

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

[IM Text]

Comme vous pouvez le constater, chaque image de l'animation comporte un très grand nombre de couleurs. Non seulement chaque trame a un nombre de couleurs différent, mais la première et la troisième trames sont très semblables du point de vue des couleurs, sans être tout à fait identiques. Cependant, le format de fichier GIF ne pouvant enregistrer qu'un maximum de 256 couleurs par trame, lorsqu'ImageMagick a enregistré cela au format GIF, il l'a fait de la manière la plus rapide et la plus fruste possible… Il a réduit le nombre de couleurs de chaque trame de l'animation (un processus appelé quantification des couleurs)…

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

[IM Text]

Parce que le nombre réduit de couleurs de chaque trame est légèrement différent, IM a également dû fournir une palette distincte pour chaque trame de l'animation. Cela signifie que le fichier GIF possède une « table de couleurs globale », ce qui est toujours le cas, mais aussi trois « tables de couleurs locales » distinctes. La commande « magick identify » ne peut pas vous indiquer combien de telles tables de couleurs locales un fichier GIF possède, car l'information est trop spécifique au format, et sans importance pour le traitement d'image qu'IM effectue normalement. En revanche, le programme plus spécialisé « [Giftrans](http://www.ict.griffith.edu.au/anthony/software/#giftrans) » peut vous indiquer combien de tables de couleurs locales de bas niveau ont été utilisées…

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

[IM Text]

Comme vous pouvez le voir, cette animation possède [IM Text] tables de couleurs locales, soit une de moins que le nombre de trames présentes dans l'image, exactement comme je l'avais prédit. Non seulement chaque trame a un jeu de couleurs différent, mais aussi un motif de couleurs légèrement différent (le motif de tramage de l'image), comme décrit dans Problèmes des tramages à correction d'erreur. Normalement, ce fonctionnement par défaut de la quantification et du tramage des couleurs d'IM est très bon, et parfaitement adapté aux images, en particulier aux photos réelles. De fait, les trames individuelles d'une animation auront en général un très bel aspect. Tous les problèmes surgissent lorsque nous essayons ensuite d'enchaîner ces trames réduites individuellement en une seule séquence d'animation.

Optimiser les trames avant les couleurs ?

Comme vous l'avez vu ci-dessus, enregistrer une animation directement au format GIF fonctionne, mais vous obtiendrez bon nombre de différences de couleurs d'une trame à l'autre, ce qui est mauvais pour l'optimisation des trames ultérieure (comme vous le verrez plus loin). Pour éviter que les différences de couleurs ne causent de tels problèmes, vous pouvez réaliser l'optimisation des trames avant d'enregistrer l'animation, évitant ainsi les différences de couleurs introduites d'une trame à l'autre. Sachez toutefois qu'optimiser les trames avant de réduire les couleurs modifie néanmoins la dynamique de la réduction des couleurs. Souvent, une moindre part des zones statiques et immobiles apparaîtra dans la sous-trame optimisée, ce qui signifie que la quantification des couleurs pour cette trame peut accorder à ces couleurs moins d'importance, et donc moins de couleurs.

Optimisation floue des couleurs

Il arrive cependant que vous n'ayez pas accès à l'animation d'origine avant son enregistrement au format GIF. C'est particulièrement vrai si vous avez téléchargé l'animation d'origine depuis le WWW. Cela signifie que vous disposez déjà d'une animation dont toutes ces distorsions de couleurs GIF sont déjà présentes, sources de problèmes pour les optimisations ultérieures. Or, parce qu'un jeu de couleurs légèrement différent est utilisé d'une trame à l'autre, et qu'un motif de pixels différent est employé pour chaque trame de l'animation, chaque trame peut être considérée comme une image totalement différente. Par exemple, comparons les première et troisième trames, qui partagent une grande partie de la même image d'arrière-plan… |

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

[IM Output]
Les zones rouges de l'exemple ci-dessus montrent deux zones carrées pleines correspondant aux endroits qui diffèrent, exactement comme on s'y attendrait. Mais elles montrent aussi des bandes de différences de couleurs qui soulignent l'arrière-plan des deux trames. Elles représentent le motif de tramage « grouillant » le long des bords du dégradé d'arrière-plan, là où des pixels de couleurs différentes ont été utilisés pour représenter exactement le même arrière-plan. C'était par ailleurs la paire de trames présentant le moins de perturbations d'arrière-plan dues à l'usage de jeux de couleurs et de motifs de tramage différents. Les différences réelles entre trames consécutives sont bien pires, produisant une différence quasi uniformément rouge. | _Des différences d'image comme celles-ci posent aussi problème si vos images source ont été stockées au format JPEG. Ce format utilise une méthode de compression avec perte qui (même à 100 % de qualité) provoque de légères différences de couleurs dans les images. Ces différences sont toutefois généralement confinées à un halo autour des zones de différence réelles, plutôt que réparties sur toute l'image.

Tout ce que je peux dire, c'est : évitez les images JPEG pour un usage dans les animations, à moins de prévoir d'utiliser une seule image comme arrière-plan statique pour TOUTES vos trames._
---|---
Comme tant de pixels de l'animation diffèrent d'une trame à l'autre, il n'est pas surprenant que, lorsqu'on essaie d'optimiser les trames de l'animation, on n'obtienne aucune optimisation du tout…

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

[IM Output]

Cependant, la plupart des différences de couleur entre les parties inchangées des trames de l'animation sont en réalité assez petites. Ce n'aurait pas été une très bonne réduction des couleurs si tel n'avait pas été le cas. Cela signifie qu'en demandant à IM d'assouplir un peu ses comparaisons de couleurs, vous pouvez lui demander d'ignorer les différences de couleurs mineures. Cela se fait en réglant un facteur de flou (Fuzz) approprié.

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

[IM Output]

Comme vous pouvez le voir, avec l'ajout d'un léger facteur de flou (Fuzz), IM va désormais ignorer les pixels qui ne diffèrent que légèrement, produisant une optimisation des trames convenable. L'ampleur du facteur de flou nécessaire dépend de la difficulté qu'IM a rencontrée à réduire les couleurs des images d'origine. Dans ce cas, pas beaucoup, un très faible facteur suffisait donc. Si un faible facteur de flou produit un résultat acceptable, contentez-vous de le régler pour votre optimisation des trames et votre optimisation de la transparence. Rappelez-vous simplement que vous avez encore une table de couleurs distincte pour chaque trame à prendre en charge, ce qui fait l'objet du point suivant. Notez aussi que l'optimisation des trames a décidé d'utiliser une suppression Previous pour la deuxième trame. Autrement dit, après affichage de la deuxième trame, l'image revient à la suppression de la trame précédente (la première image) avant superposition. Cela a produit une image de superposition plus petite que si aucune suppression n'avait été employée tout du long. Si vous vouliez simplement une animation par superposition, n'utilisant qu'une suppression None tout du long, vous auriez pu utiliser l'ancien opérateur Deconstruct (aussi connu sous le nom de Layers CompareAny) pour la générer à la place.

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

[IM Output]

Génération d'une table de couleurs globale unique

Comme chaque trame a un jeu de couleurs différent, IM a été contraint d'enregistrer l'image avec une table de couleurs distincte pour chaque trame : une table globale pour la première trame, et 3 tables de couleurs locales pour les trames suivantes. Par exemple, ici j'ai utilisé le programme très simple « [Giftrans](http://www.ict.griffith.edu.au/anthony/software/#giftrans) » pour indiquer combien de tables de couleurs de trame ont été créées.

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

[IM Text]

Pour une animation entièrement coalescée (ou du type pellicule de film), avoir des tables de couleurs distinctes pour chaque trame est parfaitement acceptable et raisonnable, et dans de telles situations ce n'est pas un problème. Autrement dit, pour des diaporamas d'images très différentes, des tables de couleurs distinctes produiront le meilleur rendu. C'est d'ailleurs le comportement normal d'IM. Toutes ces tables de couleurs supplémentaires sont toutefois très coûteuses, car chaque table de couleurs peut occuper beaucoup d'espace. Jusqu'à 768 octets (256 couleurs × 3 octets par couleur, soit 3/4 de kilo-octet) pour chaque trame de l'image. Non seulement cela, mais la compression GIF ne compresse pas ces tables de couleurs, uniquement les données de pixels ! Si consacrer autant d'espace fichier à des tables de couleurs distinctes pose problème, en particulier pour une image qui ne change pas beaucoup de couleur, comme c'est le cas de la plupart des animations GIF, vous pouvez alors demander à IM de n'utiliser que la table de couleurs globale requise, sans ajouter de table de couleurs locale. ---Pour supprimer les palettes de couleurs locales, toutes les images doivent devenir de type palette et utiliser toutes la même palette. En ligne de commande, vous pouvez le faire en réglant un « -map image » pour définir la palette de la commande. Vous ne pouvez pas utiliser -colors, car cela agit sur les images individuelles. La solution en ligne de commande est une option spéciale « [+map](https://imagemagick.org/command-line-options/#map) », qui réalise une réduction globale des couleurs vers une palette commune ajoutée à toutes les images. NOTE : toute modification de l'image invalidera probablement la palette, aussi, tandis que la réduction des couleurs doit être faite AVANT vos optimisations de trame et/ou de compression GIF, la palette commune doit venir en dernier, juste avant l'enregistrement. Si « [+map](https://imagemagick.org/command-line-options/#map) » n'a pas besoin de réduire le nombre de couleurs d'une image, il ne le fera pas et ne tramera pas les couleurs, il se contentera d'ajouter une palette commune à toutes les images. --- IM peut générer une table de couleurs globale unique si toutes les trames utilisent la même palette de couleurs. Dans IM, les palettes de couleurs ne sont attribuées à une image que par leur lecture depuis un format d'image utilisant une telle palette, ou par leur attribution au moyen de l'opérateur de réduction des couleurs « [-map](https://imagemagick.org/command-line-options/#map) ». Voir Tramage avec palette prédéfinie pour plus de détails. Une façon de générer cette table de couleurs unique est simplement d'« [-append](https://imagemagick.org/command-line-options/#append) » toutes les trames ensemble, puis d'utiliser la commande « [-colors](https://imagemagick.org/command-line-options/#colors) » pour réduire le nombre de couleurs à un jeu minimal (moins de 256, ou plus petit si vous voulez une table de couleurs encore plus petite). La table de couleurs obtenue peut ensuite être appliquée à l'image d'origine au moyen de « [-map](https://imagemagick.org/command-line-options/#map) ». Par exemple, ici je réduis l'image à un jeu unique de 64 couleurs. Cela utilise le registre en mémoire MPR spécial pour attribuer la palette générée à la commande « [-map](https://imagemagick.org/command-line-options/#map) ». |

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

[IM Output]
Maintenant, si vous examinez l'animation obtenue à l'aide de « [Giftrans](http://www.ict.griffith.edu.au/anthony/software/#giftrans) », vous constaterez que l'image utilise désormais une seule table de couleurs « globale », plutôt qu'une table de couleurs distincte pour chaque trame. | _J'utilise une couleur « [-background](https://imagemagick.org/command-line-options/#background) » « None » avant de concaténer les images ensemble, ce qui vous permet d'appliquer ceci à des animations non coalescées, sans risquer d'ajouter des couleurs superflues inutiles.

Le réglage « [-quantize](https://imagemagick.org/command-line-options/#quantize) » spécial vers l'espace colorimétrique « transparent » a été utilisé pour garantir qu'IM ne tente pas de générer de couleurs semi-transparentes dans sa palette. Chose inutile, puisque nous enregistrons le résultat en GIF, qui ne gère pas la semi-transparence.

Enfin, je réduis à 63 couleurs, pour laisser de la place à une couleur transparente. Certaines animations ont besoin de transparence, tandis que d'autres (comme celle-ci) peuvent en avoir encore besoin plus tard pour l'optimisation de la compression._
---|---
Pour simplifier cela, IM propose aussi une option spéciale « [+map](https://imagemagick.org/command-line-options/#map) » qui génère une palette de couleurs commune (de 256 couleurs) sur l'ensemble des trames, en l'appliquant globalement. C'est bien plus simple que la méthode manuelle ci-dessus. |

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

[IM Output]
Cela a donné [IM Text] tables de couleurs « locales » (ou supplémentaires et indésirables) dans l'image obtenue. J'utiliserai la version à table de couleurs unique de l'animation pour les sections d'optimisation suivantes, même si vous pourriez en réalité le faire à n'importe quel moment de vos optimisations d'animation, et surtout avant l'enregistrement final. Grâce à l'optimisation des tables de couleurs, l'animation qui faisait [IM Text] octets pour notre GIF converti directement fait désormais [IM Text] octets, après usage de l'opérateur « [+map](https://imagemagick.org/command-line-options/#map) ». Plus une animation a de trames (et de « tables de couleurs locales »), plus l'économie est grande. Or, comme toute modification d'une animation supprime en général la palette enregistrée de chacune des images, il est important que l'opérateur « [+map](https://imagemagick.org/command-line-options/#map) » soit la toute dernière opération avant l'enregistrement de l'animation en GIF. Rappelez-vous

La suppression des palettes de couleurs locales doit être la dernière optimisation, avant l'enregistrement au format GIF.

Tramage ordonné, supprimer le « grésillement »

En construction

Notez cependant que dans toutes les techniques examinées jusqu'ici, chacune peut présenter un motif de tramage qui change d'une superposition à l'autre. Un grouillement des pixels qui peut ressembler à de la neige de télévision.

... petit nombre de couleurs ...

Avec une optimisation de trame d'une petite zone immobile, vous pouvez même obtenir des zones rectangulaires de grésillement qui paraissent encore pires. ... Tramage ordonné ... Pour l'instant, reportez-vous à la Vidéo vers GIF, synthèse de l'optimisation, plus pratique et moins détaillée.


Optimisation de la compression

Une fois votre animation enregistrée au format GIF, après avoir géré les pixels semi-transparents et appliqué des optimisations de couleurs et de trames, vous pouvez aussi obtenir quelques réductions de taille de fichier supplémentaires en composant avec l'algorithme de compression du GIF. La compression LZW ou la compression RLE que le format de fichier GIF peut utiliser compressera mieux si elle trouve de plus grandes zones de couleur constante, ou des séquences de pixels qui se répètent encore et encore.

Optimisation de la transparence

Comme vous l'avez vu dans l'optimisation des trames, une image superposée se contentera souvent de répéter ce qui est déjà affiché. Autrement dit, elle superpose les mêmes pixels colorés que ceux déjà présents une fois les méthodes de suppression GIF appliquées. Mais pourquoi se donner la peine de répéter ces pixels ? Si vous utilisez déjà la transparence dans une image, vous disposez d'une couleur de pixel transparente. Or, en convertissant ces zones en transparence, vous obtenez de plus grandes zones de pixels transparents uniformes. Cela peut mieux se compresser qu'un mélange de couleurs différentes nécessaire pour reproduire la même zone superposée. Par exemple, voici une animation par superposition simple, optimisée en trames [IM Output] [IM Output]
Utilisons maintenant la méthode « **OptimizeTransparency** » de « [-layers](https://imagemagick.org/command-line-options/#layers) » (ajoutée dans IM v6.3.4-4) pour remplacer par de la transparence tout pixel qui ne change pas le résultat affiché.
  magick bunny_bgnd.gif -layers OptimizeTransparency \
                                    +map   bunny_bgnd_opttrans.gif
  gif_anim_montage bunny_bgnd_opttrans.gif bunny_bgnd_opttrans_frames.gif

[IM Output]
[IM Output]
Comme vous pouvez le voir, les sous-trames comportent désormais de grandes zones transparentes, qui n'affectent pas l'animation résultante finale. Les zones qui nécessitent un changement de pixels sont toujours superposées, mais celles qui ne changent pas ont été rendues transparentes. Cela inclut aussi l'intérieur de l'objet animé, y laissant des « trous » d'aspect plutôt hideux. Comme les plus grandes zones de couleur transparente constante se compressent (en théorie) mieux, l'animation « désordonnée » obtenue est beaucoup plus petite, réduisant la taille de fichier du résultat optimisé en trames de [IM Text] octets à [IM Text] octets. C'est une économie assez importante pour un effort très minime. Notez que la méthode d'optimisation n'avait pas besoin d'une animation coalescée, et que la taille des sous-trames reste inchangée, afin de préserver les besoins de suppression de cette trame et des trames suivantes. Ainsi, toute économie tient uniquement à l'amélioration des taux de compression pour le même nombre de pixels dans l'animation, et non à une réduction du nombre réel de pixels enregistrés dans le fichier. Cela devrait donc être fait après avoir mené à bien toute optimisation des trames nécessaire, comme l'une de vos dernières étapes d'optimisation.

FUTURE: link to a 'remove background' from animation

Bien entendu, comme la plupart des autres méthodes de « [-layers](https://imagemagick.org/command-line-options/#layers) » (comparaison ou optimisation), vous pouvez spécifier un facteur de flou (Fuzz) pour ajuster à quel point des couleurs sont considérées comme « semblables ». Cela vous permet de gérer des animations mal tramées en couleur, même si, si vous avez étudié l'optimisation des couleurs ci-dessus, vous ne devriez pas avoir ce problème. L'outil libre d'animation GIF « **[InterGIF](http://utter.chaos.org.uk/~pdh/software/intergif.htm)** » propose aussi ce même type d'optimisation de la compression par transparence montré ci-dessus, mais sans la possibilité de gérer aussi un « facteur de flou » pour rendre également transparents les changements de couleurs « proches ». Je ne le recommande pas, sauf comme solution de repli lorsqu'IM n'est pas disponible.

Optimisation LZW - (hors IM)

Certaines applications peuvent optimiser davantage le taux de compression des images d'une animation pour la rendre encore plus petite. Mais pour cela, il faut une connaissance spécialisée de la compression LZW que le format de fichier image GIF utilise généralement. Fondamentalement, si une séquence de pixels précise a déjà été traitée par l'algorithme de compression LZW, il ne se donnera pas la peine de la transformer en pixels transparents, car cela n'améliorerait pas la compression de l'image. Cela paraît étrange, mais ça fonctionne. Malheureusement, ImageMagick ne fait pas cela, car c'est un processus si complexe qu'il faut beaucoup de savoir-faire et de ressources pour obtenir une heuristique suffisamment bonne, capable de produire un bon résultat dans le cas général. Je peux néanmoins vous donner un exemple pratique de cette technique à l'aide de l'application « [Gifsicle](http://www.lcdf.org/gifsicle/) » à son plus haut niveau d'optimisation, « -O2 ». |

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

[IM Output]

[IM Output]

L'optimisation de la compression LZW a réduit l'image de [IM Text] octets, avec la simple optimisation de la transparence, à [IM Text] octets pour « Gifsicle ». Pas une grande amélioration. L'aspect le plus important, toutefois, est que si l'optimisation LZW a converti en transparence des pixels inchangés (comme nous l'avons fait avec l'optimisation de la transparence ci-dessus), elle n'a pas modifié une séquence de pixels déjà rencontrée. Autrement dit, seuls les groupes de pixels qui n'avaient pas déjà été répétés au sein de l'animation ont été modifiés, car ces pixels se compresseraient (vraisemblablement) déjà bien grâce aux motifs de compression LZW. Notez que le choix des pixels à rendre transparents, pour générer des motifs de pixels répétés, est très complexe et difficile, et peut même dépendre de l'implémentation LZW exacte. C'est une heuristique, non un algorithme parfaitement prévisible. Ainsi, différents programmes produiront en général des résultats différents selon l'image précise compressée. Un programme peut produire un meilleur taux de compression pour une image, et un autre peut être meilleur pour une image différente.

Optimisation LZW avec perte - (hors IM)

Une autre méthode d'amélioration de la compression consistait à modifier légèrement les couleurs des pixels eux-mêmes vers des « correspondances de couleurs proches », afin d'accroître la répétition des références de couleur dans l'image. Un motif répété se compresse naturellement mieux, et peut donc produire des taux de compression supérieurs. Un dérivé de l'application « Gifsicle » précédente, connu sous le nom de giflossy, génère lui aussi un programme « gifsicle », mais doté de l'option de modifier l'image de façon mineure (elle est « avec perte ») pour réduire bien davantage la taille des images GIF, en particulier dans les animations. | |

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

[IM Output]

[IM Output]


Created: 22 March 2007 ((sub-division of "animation")
Updated: 23 April 2007
Author: Anthony Thyssen, Anthony.Thyssen@gmail.com
Examples Generated with: [version image]
URL: https://usage.imagemagick.org/anim_opt/

Cela a abouti à une taille de [IM Text], soit une réduction de taille étonnante d'un tiers. Malheureusement, cette méthode implique de modifier l'image obtenue, et l'optimisation est donc avec perte, car elle peut perdre de subtiles informations de couleur. En revanche, elle vous permet de compresser les trames individuelles, plutôt que de procéder à une optimisation de trame à trame. Ici par exemple, j'ai généré une image de différence entre la compression LZW sans perte précédente et une compression LZW avec perte. |

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

[IM Output]

Comme vous pouvez le voir, la quasi-totalité des modifications de couleur portait sur l'image d'arrière-plan « herbe » d'origine, plutôt que sur le lapin de dessin animé. Fondamentalement, elle a modifié les choses juste assez pour faire une énorme différence, et pour cette image, sans différence réellement perceptible à l'œil. Bien entendu, la quantification et le tramage des couleurs sont eux-mêmes une opération avec perte, et sont généralement nécessaires de toute façon, aussi utiliser une méthode de compression avec perte pour les images GIF, et les animations GIF, n'est pas considéré comme très grave. Un autre exemple d'un tel algorithme, breveté pour un usage par Photoshop, voirUS Patent 7031540 - Transformation to increase the lempel-ziv compressibility of images with minimal visual distortion. C'est ardu à lire, mais cela détaille les méthodes employées pour obtenir une meilleure compression.

Optimisation LZW par tramage ordonné

Comme le processus de tramage est en général une opération plus destructrice que les optimisations LZW, une meilleure solution peut consister à tenter d'introduire les motifs répétables dans le cadre du processus de tramage lui-même. Cela peut être obtenu en utilisant un tramage ordonné pour produire de tels motifs, et donc des économies de compression LZW bien plus fortes que toutes les méthodes d'optimisation LZW précédentes. En prime, cela peut aussi améliorer l'optimisation des trames des animations réelles à arrière-plan statique. Ce serait particulièrement vrai si vous nettoyez artificiellement l'arrière-plan pour qu'il devienne réellement un arrière-plan statique inchangé. Bien entendu, l'optimisation de la compression par tramage ordonné ne fonctionne que pour les images qui n'ont pas déjà été tramées ou autrement optimisées en couleur. Elle ne fonctionne donc que pour les animations qui n'ont pas encore été optimisées pour le format d'image GIF. En outre, le tramage ordonné d'IM ne fonctionne actuellement que pour une palette de couleurs uniforme. IM n'a pas encore d'implémentation du tramage ordonné avec palette « meilleures couleurs » ou « fournie par l'utilisateur », bien que j'aie vu des programmes qui utilisent un tel algorithme pour des palettes très limitées (et fixes). Connaissez-vous un tel algorithme ? Pour un exemple pratique d'usage du tramage ordonné en vue d'une meilleure optimisation de la compression LZW, voir Vidéo tramée par tramage ordonné.

Autre optimisation LZW

D'autres améliorations de l'optimisation LZW peuvent aussi être obtenues par d'autres réarrangements du « motif de tramage » dans l'image. Et certains outils GIF savent faire exactement cela. Toutefois, toute optimisation de ce genre devrait toujours être vérifiée par un œil humain avant d'être approuvée, car il peut parfois en résulter des changements de couleur subtils mais fâcheux.

Synthèse de l'optimisation de la compression

Voici une synthèse complète des tailles de fichier finales obtenues au moyen des optimisations de compression.

[IM Text]

Comme vous pouvez le constater, seules de légères améliorations de la taille finale de l'animation ont été obtenues au moyen de la très complexe optimisation LZW, par rapport à l'optimisation de la transparence intégrée. Cependant, les résultats varient aussi grandement selon les nombreux programmes d'optimisation GIF disponibles et l'animation précise à optimiser. Si vous devez vraiment extraire le dernier octet d'un fichier, alors une optimisation LZW peut être exactement ce qu'il vous faut. Et s'il vous faut vraiment les tout meilleurs résultats, vous devriez essayer plusieurs programmes différents (et donc des implémentations d'heuristiques différentes) pour voir lequel compresse le mieux votre animation particulière, y compris les autres fonctions d'optimisation qu'ils proposent. En général, une optimisation de la transparence suffit amplement pour la plupart des usages. L'optimisation LZW ne produisant qu'un résultat légèrement meilleur, soit une économie très mineure pour les tailles de transmission réseau, plutôt que pour la taille de stockage sur disque, car cette dernière utilise de plus grands « morceaux » ou « blocs » de stockage. Pour cette raison, j'estime que l'optimisation LZW est excessive, et je ne pense pas qu'elle vaille l'effort, ni l'argent (la plupart de ces outils sont vendus commercialement). | _Malheureusement, j'ai constaté que ces optimiseurs GIF ne gèrent pas très bien TOUS les types d'animations préoptimisées.

Par exemple, mes tests montrent que « [Gifsicle](http://www.lcdf.org/gifsicle/) » échoue à gérer une animation déjà optimisée au moyen d'une technique d'« suppression Background ».

D'un autre côté, j'ai constaté qu'« [InterGIF](http://www.chaos.org.uk/~pdh/software/intergif.htm) » ne gère pas les animations déjà optimisées pour utiliser un canevas initial et une technique d'« suppression Previous ». Il est aussi limité à l'usage de l'optimisation de la transparence, qu'IM fournit désormais.

Je vous recommande donc de ne pas mélanger les utilitaires d'optimisation GIF en injectant la sortie d'un utilitaire dans un autre. Du moins, pas sans d'abord coalescer l'animation pour supprimer toute optimisation de trame antérieure.

IM, Gifsicle et InterGIF fournissent tous de telles options de coalescence pour supprimer leurs propres optimisations, même si je ne peux garantir que les applications hors IM coalesceront TOUTES les animations correctement. IM le fera.

_
---|---
Parce que vous ne pouvez pas utiliser ces programmes de façon fiable avec les techniques avancées d'optimisation des trames d'IM (qui sélectionnent et basculent automatiquement vers différentes techniques de suppression GIF), j'ai souvent constaté qu'IM produira souvent un résultat global meilleur que le simple usage de ces optimiseurs de compression LZW. Je vous suggère aussi de coalescer à nouveau le résultat ensuite et de comparer ses trames à l'animation non optimisée d'origine, afin de vous assurer que le programme hors IM n'a pas d'une manière ou d'une autre entièrement gâché l'animation (voir la note ci-dessus). Croyez-moi, je l'ai vu arriver, et les scripts devraient revérifier que les animations restent valides.
Un autre tutoriel (utilisant des outils Windows) sur ce type d'optimisation est WebReference Frame Optimation. Notez que le site est mal nommé, car il porte en réalité sur l'optimisation de la compression.


Optimisations mineures

Il existe quelques autres techniques d'optimisation utilisables avec les animations GIF, souvent si évidentes qu'on les néglige.

  • Supprimer les commentaires GIF.
    De nombreuses animations GIF comportent un long commentaire textuel ajouté. Souvent, ceux-ci ont été ajoutés automatiquement par des éditeurs graphiques en guise de publicité. Par exemple, « Gimp » ajoute par défaut « Created with The GIMP » aux images. Si le commentaire n'est pas nécessaire, c'est un gaspillage d'espace. Supprimez-les en ajoutant un opérateur « [+set](https://imagemagick.org/command-line-options/#set) comment » à la commande « magick » d'IM avant l'enregistrement du GIF. Notez toutefois que si le commentaire est un avis de droit d'auteur, il peut être malavisé de le supprimer pour des raisons juridiques.
  • Réduire le nombre de couleurs.
    Si l'animation reste correcte avec moins de couleurs, utilisez une table de couleurs plus petite. Les tables de couleurs sont toujours une puissance de deux, aussi, si vous pouvez utiliser moins de 32 couleurs, c'est bien plus petit que d'en utiliser 256. C'est d'autant plus important que les tables de couleurs ne sont pas compressées par la compression LZW utilisée pour les données d'image GIF. De plus, utiliser moins de couleurs produira en général une meilleure compression LZW, car davantage de séquences de pixels communes sont trouvées. Ce n'est cependant pas toujours le cas, car le tramage des couleurs (dû à la réduction des couleurs) peut aussi dégrader la compression. Désactiver le tramage ou utiliser un tramage ordonné peut être important ici.
  • Diviser par deux le nombre de trames visibles par l'utilisateur.
    Si vous pouvez vous accommoder d'une animation moins fluide, diviser par deux le nombre total de trames peut apporter une belle amélioration de la taille de fichier finale. Bien entendu, vous n'obtenez pas un fichier deux fois plus petit, et la qualité de l'animation est réduite. Mais cela peut produire une très forte réduction de la taille de fichier.
  • Rogner/redimensionner l'animation.
    Une taille d'image plus petite signifie une taille de fichier plus petite. Donc, si vous n'avez pas besoin d'une grande animation, n'utilisez pas une grande animation. Une petite vignette représentant une animation ou une vidéo plus grande est souvent préférable, dans une liste, à la chose elle-même.
  • Compressions alternatives.
    Si vous ne prévoyez pas d'utiliser l'animation en tant qu'animation, c'est-à-dire si vous voulez seulement la stocker, désactivez la compression LZW et compressez le fichier ENTIER avec « gzip » ou « bzip2 » pour le stockage ! Le résultat est bien plus petit, même s'il faut que les serveurs web fournissent les bons indices de « contenu » et de « compression » aux navigateurs pour qu'il soit directement utilisable par les navigateurs clients. Le serveur web « Apache » ne le fait pas par défaut, mais on peut l'y amener. Mieux encore, archivez tout le répertoire d'animations non compressées en un seul fichier, pour une compression de stockage encore meilleure.

Si vous avez d'autres idées d'optimisation, faites-le-moi savoir.


Autres sources d'information sur l'optimisation des GIF

Ce qui précède achève les diverses méthodes et techniques élémentaires de gestion des animations. Cependant, pour former un tableau complet, vous devriez poursuivre avec la page suivante des IM examples, qui détaille les techniques de gestion des problèmes réels des animations d'images. Par ailleurs, bon nombre des techniques ci-dessus sont illustrées par les exemples pratiques de l'optimisation Vidéo vers GIF. Je vous recommande aussi de lire attentivement la quantification des couleurs, si vous voulez vraiment vous atteler sérieusement aux animations GIF, car la réduction des couleurs est souvent la clé d'une bonne gestion des animations GIF. Parmi les autres sources utiles de techniques d'optimisation d'animations GIF que j'ai trouvées sur le WWW figurent…

Écrivez-moi si vous pensez avoir une page que je devrais lister ici. Je n'ajouterai que des pages au contenu utile, aucune garantie donc quant à l'ajout de votre lien.