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

Exemples ImageMagick -- Calques multi-images

Exemples ImageMagick : préface et index
Introduction aux calques
Assemblage d'images (Append) (-append)

Introduction à la superposition d'images

Comme nous l'avons déjà noté, ImageMagick ne traite pas une seule image, mais une séquence ou une liste d'images. Cela permet d'utiliser IM dans deux techniques de traitement d'image très particulières. On peut par exemple considérer chaque image de la liste comme une image isolée dans le temps, de sorte que la liste entière puisse être vue comme une animation. Ce point est exploré dans d'autres pages d'exemples d'IM. Voir Les bases de l'animation. On peut aussi considérer chaque image de la séquence comme les calques d'un jeu de transparents superposables. Autrement dit, chaque image représente une petite partie de l'image finale. Par exemple : le premier calque (le plus bas) peut représenter une image d'arrière-plan. Au-dessus, on peut placer une ombre floue et translucide. Le calque suivant contient alors l'objet qui projette cette ombre. Par-dessus, un calque comportant du texte écrit sur cet objet. On dispose ainsi d'une séquence d'images, ou « calques », qui ajoutent chacun une pièce de plus à une image beaucoup plus complexe. Chaque calque peut être déplacé, édité ou modifié de façon totalement indépendante des autres, et même enregistré dans un fichier multi-image (tel que TIFF:, MIFF: ou XCF:) ou en images séparées, en vue d'un traitement ultérieur. C'est là tout l'intérêt de la superposition en calques. Ce n'est qu'une fois tous les calques créés que l'on procède à l'aplatissement (Flatten), à la mosaïque (Mosaic) ou à la fusion (Merge) de toutes les images superposées en une seule image finale.


Assemblage d'images (Append)

L'assemblage (Append) est probablement la plus simple des opérations multi-images prévues pour manipuler plusieurs images. Il joint essentiellement la séquence d'images courante en mémoire en une colonne, ou une rangée, sans espace. L'option « [-append](https://imagemagick.org/command-line-options/#append) » assemble verticalement, tandis que la forme plus « [+append](https://imagemagick.org/command-line-options/#append) » assemble horizontalement. Par exemple, ici nous assemblons un ensemble d'images de lettres côte à côte pour former un mot élégant, de la même manière que les « glyphes » individuels, ou lettres, d'une « police » sont réunis.

  magick font_A.gif font_P.gif font_P.gif font_E.gif font_N.gif \
          font_D.gif font_E.gif font_D.gif +append  append_row.gif

[IM Output]

L'exemple ci-dessus ressemble (de façon très élémentaire) à la manière dont les polices sont gérées. Contrairement aux vraies polices, on n'est pas limité à deux couleurs, mais on peut produire des alphabets très élégants et colorés à partir d'images de caractères individuelles. Beaucoup de ces « polices d'images » sont disponibles au téléchargement sur le WWW. Un tout petit ensemble se trouve dans Anthony's Icon Library, dans Fonts for Text and Counters, où j'ai d'ailleurs trouvé la Blue Bubble Font utilisée ci-dessus. Remarquez aussi que l'opérateur « [+append](https://imagemagick.org/command-line-options/#append) » a été exécuté en dernière opération, après que toutes les images à assembler ont été ajoutées à la séquence d'images courante. C'est très pratique pour assembler un libellé à une image, par exemple… |

  magick rose: -background LawnGreen label:Rose \
          -background white  -append append_label.jpg

[IM Output]
Notez que la couleur « [-background](https://imagemagick.org/command-line-options/#background) » a servi à combler tout espace non rempli. Bien sûr, si toutes les images ont la même largeur, aucun espace ne restera à combler. À partir d'IM v6.4.7-1, le réglage « [-gravity](https://imagemagick.org/command-line-options/#gravity) » peut servir à indiquer comment les images doivent être réunies. Ainsi, dans un assemblage vertical, un réglage « Center » centrera l'image par rapport à l'image résultante finale (de même qu'un réglage « North » ou « South »). |

  magick rose: -background LawnGreen label:Rose \
          -background white -gravity center -append \
          append_center.jpg

[IM Output]
Naturellement, tout réglage de gravité « East » alignera les images sur le côté droit. |

  magick rose: -background LawnGreen label:Rose \
          -background white -gravity east -append \
          append_east.jpg

[IM Output]
Un alignement vertical similaire peut être obtenu avec « [+append](https://imagemagick.org/command-line-options/#append) » | _Avant IM v6.4.7, il était bien plus difficile d'aligner des images assemblées, ce qui impliquait généralement d'utiliser un « [-flop](https://imagemagick.org/command-line-options/#flop) » pour l'alignement à droite. Ou d'utiliser « [-extent](https://imagemagick.org/command-line-options/#extent) » ou « [-border](https://imagemagick.org/command-line-options/#border) » pour ajuster la largeur de l'image dans le cas d'assemblages centrés.

Par exemple, cela fonctionnera avec une version plus ancienne d'IM, la 6.3.2…_ | |

  magick rose: -background SkyBlue label:Rose \
          -background White -gravity center -extent 200x \
          -append -trim +repage   append_center_old.jpg

[IM Output]
On peut aussi utiliser plusieurs opérations d'assemblage dans la même commande, sans conflit ni confusion quant au résultat des opérations (ce qui n'était pas le cas avant IM v6). |

  magick font_{0,0,6,1,2}.gif +append  dragon_long.gif \
          -background none   -append   append_multi.gif

[IM Output]
Nous avons assemblé chaque rangée d'images, puis assemblé une image plus grande en dessous. C'est très simple et direct. En utilisant des parenthèses, on peut n'assembler que les chiffres après l'image plus grande. Par exemple, ici nous assemblons tous les chiffres ensemble avant de les assembler verticalement à l'image du dragon lue avant les chiffres. |

  magick dragon_long.gif  '(' font_{0,0,6,2,9}.gif +append ')' \
          -background none   -append   append_parenthesis.gif

[IM Output]
| Les parenthèses ci-dessus doivent être soit protégées par des guillemets, soit échappées par une barre oblique inverse (« \ ») lorsqu'elles sont utilisées avec un shell UNIX, sinon celui-ci les interprétera comme tout autre chose.
---|---
| Comme seules deux images étaient concernées, nous aurions pu simplement utiliser « [+swap](https://imagemagick.org/command-line-options/#swap) » ou « [-reverse](https://imagemagick.org/command-line-options/#reverse) » au lieu des parenthèses.
---|---

Assembler un tableau d'images

On peut pousser cela plus loin pour créer tout un tableau d'images, en les construisant par rangées ou par colonnes. |

  magick \( font_1.gif font_2.gif font_3.gif +append \) \
          \( font_4.gif font_5.gif font_6.gif +append \) \
          \( font_7.gif font_8.gif font_9.gif +append \) \
          \( -size 32x32 xc:none  font_0.gif +append \) \
          -background none -append   append_array.gif

[IM Output]
Techniquement, le premier jeu de parenthèses n'est pas nécessaire, puisque aucune image n'a encore été lue, mais cela rend la commande uniforme et en montre l'intention : constituer un tableau d'images. Voir aussi le mode concaténation de Montage pour une autre façon de créer des tableaux d'images de même taille. | _L'opérateur « [-append](https://imagemagick.org/command-line-options/#append) » n'assemble que les images réelles et ne se sert ni de la taille du canevas virtuel (la page de l'image) ni du décalage de l'image. Les informations de canevas virtuel semblent toutefois rester dans un état curieux, les tailles de canevas étant additionnées et le décalage fixé à une valeur indéfinie.

Cela peut être considéré comme un bogue et signifie qu'il faut réinitialiser le canevas virtuel des images d'entrée ou du résultat à l'aide de « [+repage](https://imagemagick.org/command-line-options/#repage) », avant l'enregistrement, ou avant d'utiliser l'image dans des opérations où cette information peut devenir importante.

Cette situation sera probablement corrigée lors d'une future extension de l'opération. La prudence est donc de mise, en particulier si l'on réassemble des images découpées en tuiles._
---|---

Assemblage avec chevauchement

Sur le forum d'IM, un utilisateur a demandé un moyen simple d'assembler des images avec un certain chevauchement. De nombreuses solutions ont été proposées. Voici l'une des plus simples, où l'ampleur du chevauchement est indiquée en un seul endroit. |

  magick granite: rose: -gravity east -background none \
          \( -clone 1 -chop 30x0 \) \( -clone 0,2 +append \) \
          -delete 0,2 +swap -composite append_overlap.gif

[IM Output]
L'exemple ci-dessus n'a nécessité aucun calcul de positionnement d'image, impliquant typiquement les tailles d'images, qui représenterait une solution plus générale. Voir Manipulation des calques d'images ci-dessous. Ce qu'il fait, c'est retirer la partie qui se chevauche avant d'assembler le résultat à la première image, produisant la taille d'image finale. L'image d'origine est ensuite composée (avec gravité) par-dessus pour générer le chevauchement réel. On peut l'adapter assez facilement à un chevauchement vertical, ou même à un chevauchement de droite à gauche.

Assemblage compact (Smush)

Une autre manière d'assembler des images est le « smushing ». L'opérateur « [-smush](https://imagemagick.org/command-line-options/#smush) » fonctionne à peu près comme l'opérateur d'assemblage (voir plus haut), mais il prend en argument l'espace (ou l'anti-espace) que l'on veut entre les images. Par exemple, utilisons-le pour réaliser l'exemple précédent plus simplement. |

  magick granite: rose: -background none -gravity Center \
          +smush -20 smush_overlap.png

[IM Output]
Cela fonctionne très bien, même si ce n'est pas ce à quoi l'opérateur est réellement destiné, et c'est probablement bien plus lent. Ce que smush est censé faire, c'est rapprocher au maximum des « images de forme ». Par exemple, ici je génère les lettres « A » et « V » et je les « smushe » ensemble avec le moins d'espace possible entre elles. |

  magick -background none -pointsize 72 \
          -fill red label:A -fill blue label:V \
          +smush 0 smush_append.png

[IM Output]
Remarquez comme les deux lettres ont été assemblées bien plus près que ne le ferait append, en tirant parti de l'espace vide de la « forme » des images. L'écart ci-dessus provient des pixels de bord anticrénelés des deux lettres. C'est précisément ce que « [-smush](https://imagemagick.org/command-line-options/#smush) » est conçu pour faire, mais cela demande beaucoup de calculs et se révèle donc bien plus lent que l'assemblage (voir plus haut). L'argument est un décalage pour cette position finale ; il est généralement positif pour créer un espace, mais peut être négatif pour créer un chevauchement. |

  magick -background none -pointsize 72 \
          -fill red label:A -fill blue label:V \
          +smush -15 smush_offset.png

[IM Output]
Les images peuvent se retrouver rognées de manière non documentée si une valeur négative très grande est utilisée.


Composition de plusieurs paires d'images

La composition est l'opération de bas niveau qui sert à fusionner deux images individuelles. Presque toutes les techniques de superposition se ramènent en fin de compte à fusionner des images deux par deux, jusqu'à ce qu'il n'en reste qu'une. Commençons donc par examiner les façons de réaliser une composition de bas niveau de paires d'images.

Utiliser la commande composite

La méthode traditionnelle pour combiner deux images avec ImageMagick passe par la commande « magick composite ». Cette commande ne peut combiner que deux images à la fois, en enregistrant le résultat de chaque opération dans un fichier. Cela ne vous empêche évidemment pas de l'utiliser pour superposer plusieurs images, une image à la fois… |

  magick -size 100x100 xc:skyblue composite.gif
  magick composite -geometry  +5+10 balloon.gif composite.gif composite.gif
  magick composite -geometry +35+30 medical.gif composite.gif composite.gif
  magick composite -geometry +62+50 present.gif composite.gif composite.gif
  magick composite -geometry +10+55 shading.gif composite.gif composite.gif

[IM Output]
| _Comme toutes les images d'entrée sont lues par ImageMagick AVANT l'ouverture de l'image de sortie, on peut écrire le résultat dans l'une des images d'entrée. Cela permet de travailler encore et encore sur la même image, comme montré ci-dessus, sans problème.

Ne faites pas cela avec un format d'image avec perte comme « JPEG », car les erreurs de format sont cumulatives et l'image de base se dégradera rapidement._
---|---
On peut aussi redimensionner l'image superposée, en plus de la positionner, à l'aide du réglage « [-geometry](https://imagemagick.org/command-line-options/#geometry) ». |

  magick -size 100x100 xc:skyblue comp_resize.gif
  magick composite -geometry 40x40+5+10  balloon.gif comp_resize.gif comp_resize.gif
  magick composite -geometry      +35+30 medical.gif comp_resize.gif comp_resize.gif
  magick composite -geometry 24x24+62+50 present.gif comp_resize.gif comp_resize.gif
  magick composite -geometry 16x16+10+55 shading.gif comp_resize.gif comp_resize.gif

[IM Output]
La commande « magick composite » présente aussi quelques autres avantages : on peut contrôler la façon dont l'image est dessinée sur l'arrière-plan avec l'option « [-compose](https://imagemagick.org/command-line-options/#compose) », et sa position relative est influencée par le réglage « [-gravity](https://imagemagick.org/command-line-options/#gravity) ». On peut aussi « [-tile](https://imagemagick.org/command-line-options/#tile) » la superposition pour qu'elle couvre simplement l'image d'arrière-plan, sans avoir à préciser de limites de pavage. C'est une possibilité offerte uniquement par « magick composite ». Le gros inconvénient de cette méthode est que l'on utilise plusieurs commandes, et qu'IM doit écrire l'image de travail, soit dans un tube, soit sur le disque, pour que la commande suivante la relise. Pour d'autres exemples d'utilisation de la commande « magick composite » afin de superposer des images sur d'autres images, voir « Annoter en superposant des images » et « Positionnement d'images à l'aide de la gravité ».

L'opérateur composite de convert

L'opérateur « [-composite](https://imagemagick.org/command-line-options/#composite) » est disponible dans la commande « magick ». Pour plus de détails, voir La composition d'images dans IM. Cela permet de faire la même chose que ci-dessus, mais en une seule commande. |

  magick -size 100x100 xc:skyblue \
          balloon.gif  -geometry  +5+10  -composite \
          medical.gif  -geometry +35+30  -composite \
          present.gif  -geometry +62+50  -composite \
          shading.gif  -geometry +10+55  -composite \
          compose.gif

[IM Output]
Ceci crée d'abord une image de canevas de couleur « skyblue », puis superpose chacune des images suivantes sur ce canevas aux emplacements indiqués. Or « [-geometry](https://imagemagick.org/command-line-options/#geometry) » est un opérateur très particulier : non seulement il définit la position de superposition pour l'opération « [-composite](https://imagemagick.org/command-line-options/#composite) » suivante, mais il « [-resize](https://imagemagick.org/command-line-options/#resize) » aussi la dernière image (et seulement la dernière) de la séquence d'images courante. |

  magick -size 100x100 xc:skyblue \
          balloon.gif  -geometry 40x40+5+10   -composite \
          medical.gif  -geometry      +35+30  -composite \
          present.gif  -geometry 24x24+62+50  -composite \
          shading.gif  -geometry 16x16+10+55  -composite \
          compose_geometry.gif

[IM Output]
Notez qu'il est recommandé d'éviter cet effet secondaire de « redimensionnement » de « [-geometry](https://imagemagick.org/command-line-options/#geometry) », même s'il est commode. C'est avant tout un effet de compatibilité ascendante qui peut, dans certaines situations, produire d'autres effets. Voici la recommandation plus explicite… |

  magick -size 100x100 xc:skyblue \
          \( balloon.gif -resize 40x40 \) -geometry +5+10   -composite \
          \( medical.gif               \) -geometry +35+30  -composite \
          \( present.gif -resize 24x24 \) -geometry +62+50  -composite \
          \( shading.gif -resize 16x16 \) -geometry +10+55  -composite \
          compose_resize.gif

[IM Output]

Dessiner plusieurs images

Toujours avec « magick », vous pouvez aussi utiliser des primitives de dessin pour superposer des images sur son canevas de travail. |

  magick -size 100x100 xc:skyblue \
          -draw "image over  5,10 0,0 'balloon.gif'" \
          -draw "image over 35,30 0,0 'medical.gif'" \
          -draw "image over 62,50 0,0 'present.gif'" \
          -draw "image over 10,55 0,0 'shading.gif'" \
          drawn.gif

[IM Output]
Vous pouvez bien sûr aussi indiquer un redimensionnement pour l'image superposée… |

  magick -size 100x100 xc:skyblue \
          -draw "image over  5,10 40,40 'balloon.gif'" \
          -draw "image over 35,30  0,0  'medical.gif'" \
          -draw "image over 62,50 24,24 'present.gif'" \
          -draw "image over 10,55 16,16 'shading.gif'" \
          drawn_resize.gif

[IM Output]
Les images « dessinées » peuvent aussi être pivotées, mises à l'échelle et déformées par transformation affine durant la superposition. Cela peut toutefois être délicat à obtenir comme on le souhaite. Les images dessinées sont influencées par « [-gravity](https://imagemagick.org/command-line-options/#gravity) », tout comme le texte.


Superposition de plusieurs images

La véritable superposition d'images requiert des méthodes pour combiner plusieurs images ensemble, sans avoir à composer individuellement chaque paire d'images. C'est là que les diverses méthodes de l'opérateur [-layers](https://imagemagick.org/command-line-options/#layers) prennent tout leur sens. L'ordre des images superposées peut être important, aussi est-il bon de comprendre les opérateurs de séquence ou de liste d'images particuliers. Notez que la manipulation des « images en calques » est pratiquement identique à celle des « trames d'animation ». Il est donc recommandé de consulter aussi Les bases de l'animation et Modifications d'animation pour les techniques de traitement de « calques » ou « trames » individuels. En fait, les animations utilisent souvent le même opérateur [-layers](https://imagemagick.org/command-line-options/#layers) pour traiter les images.

Aplatissement (Flatten) - sur une image d'arrière-plan

L'opérateur de liste d'images « [-layers](https://imagemagick.org/command-line-options/#layers) **flatten** » (ou son raccourci « [-flatten](https://imagemagick.org/command-line-options/#flatten) ») « compose » essentiellement chacune des images données sur un arrière-plan pour former une seule image. Les positions des images sont toutefois spécifiées par leur décalage de canevas virtuel, ou page courant. Par exemple, ici je crée un joli canevas et j'indique chacune des images à superposer sur ce canevas. |

  magick -size 100x100 xc:skyblue \
          -fill dodgerblue -draw 'circle 50,50 15,25' \
          \( -page +5+10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -layers flatten  flatten_canvas.gif

[IM Output]
| _Depuis IM v6.3.6-2, l'opérateur « [-flatten](https://imagemagick.org/command-line-options/#flatten) » n'est qu'un alias de la méthode « [-layers](https://imagemagick.org/command-line-options/#layers) 'flatten' ».

Ainsi, l'option « [-flatten](https://imagemagick.org/command-line-options/#flatten) » peut être vue comme un raccourci de la méthode « [-layers](https://imagemagick.org/command-line-options/#layers) » du même nom._
---|---
Vous n'avez pas besoin de créer un canevas initial comme nous l'avons fait ci-dessus ; vous pouvez au contraire laisser « [-flatten](https://imagemagick.org/command-line-options/#flatten) » en créer un pour vous. La couleur du canevas sera la couleur « [-background](https://imagemagick.org/command-line-options/#background) » courante, tandis que sa taille est définie par la taille du canevas virtuel de la première image. |

  magick \( -page 100x100+5+10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( --page +62+50        present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -layers flatten  flatten_page.gif

[IM Output]
| _Si le réglage « [-gravity](https://imagemagick.org/command-line-options/#gravity) » influence le placement des images défini via les réglages « [-geometry](https://imagemagick.org/command-line-options/#geometry) », il n'influence pas le positionnement des images par décalages de canevas virtuel défini via le réglage « [-page](https://imagemagick.org/command-line-options/#page) ». Cela fait partie de la définition de ces décalages. Voir Décalages de géométrie et de page pour plus de détails.

Si un placement avec « [-gravity](https://imagemagick.org/command-line-options/#gravity) » est nécessaire, examinez soit les méthodes de composition multi-images ci-dessus, soit la méthode particulière de composition en calques qui peut gérer les deux méthodes de positionnement simultanément._
---|---
Si une image n'apparaît pas dans la zone du canevas virtuel définie, elle sera soit rognée, soit ignorée, selon le cas. Par exemple, ici nous avons utilisé une taille de canevas plus petite, de sorte que les images ultérieures n'apparaissent pas complètement sur ce canevas. |

  magick \( -page 75x75+5+10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -flatten  flatten_bounds.gif

[IM Output]
L'usage normal de l'aplatissement (Flatten) est de fusionner plusieurs « calques » d'images. Vous pouvez générer diverses parties d'une image plus grande, généralement à l'aide de parenthèses pour limiter les opérateurs d'image au seul « calque » en cours de génération, puis aplatir le résultat final. Par exemple, un usage typique consiste à créer un calque d'image d'ombre sur lequel l'image originale est aplatie. Par exemple… |

  magick balloon.gif \( +clone  -background navy  -shadow 80x3+5+5 \) +swap \
          -background none   -flatten   flatten_shadow.png

[IM Output]
Notez que, comme je veux l'ombre sous l'image originale, il m'a fallu échanger les deux images pour les placer dans le bon ordre. | _Utiliser l'aplatissement (Flatten) pour ajouter des images d'ombre générées n'est pas recommandé, car les images d'ombre générées peuvent avoir des décalages d'image négatifs.

La solution recommandée, donnée dans la section sur les images d'ombre, est d'utiliser la technique plus avancée de fusion de calques, que nous verrons plus loin._
---|---
Comme le canevas virtuel ne consiste qu'en une taille, l'image résultante aura cette taille, mais sans décalage de canevas virtuel ; vous n'avez donc pas à vous soucier des décalages présents dans l'image finale. Cette utilisation du canevas virtuel pour définir le canevas sur lequel superposer l'image permet de s'en servir pour ajouter une bordure autour d'une image. Par exemple, ici je fixe la taille et le décalage virtuel d'une image pour la « remplir » jusqu'à une taille précise. |

  magick medical.gif -set page 64x64+20+20 \
          -background SkyBlue   -flatten   flatten_padding.gif

[IM Output]
Il existe bien sûr de meilleures façons de compléter une image (Pad) pour qu'IM centre automatiquement l'image dans la zone plus grande. Curieusement, le même traitement peut servir à « rogner » ou découper (Crop) une image sur un canevas virtuel plus petit que l'image originale. Dans ce cas, cependant, il faut utiliser un décalage négatif pour positionner l'emplacement du « rognage », car vous décalez l'image et non la « fenêtre » de rognage. |

  magick logo:  -repage 100x100-190-60  -flatten  flatten_crop.gif

[IM Output]
Bien entendu, un rognage par fenêtre (Viewport Crop) ferait cela mieux encore, sans le traitement supplémentaire de génération de canevas et de superposition qu'effectue aussi « [-flatten](https://imagemagick.org/command-line-options/#flatten) ». Il n'« étendra » pas non plus l'image elle-même pour couvrir toute la fenêtre si l'image n'était que partiellement contenue dans celle-ci. Un mésusage courant de l'opérateur « [-flatten](https://imagemagick.org/command-line-options/#flatten) » consiste à supprimer la transparence d'une image. C'est-à-dire éliminer toute transparence qu'une image peut avoir en la superposant sur la couleur d'arrière-plan. Cela ne fonctionne cependant pas lorsque plusieurs images sont en jeu et n'est donc plus recommandé.

Mosaïque (Mosaic) - extension du canevas

L'opérateur « [-layers](https://imagemagick.org/command-line-options/#layers) **mosaic** » (ou son raccourci « [-mosaic](https://imagemagick.org/command-line-options/#mosaic) ») ressemble davantage à une version à canevas extensible de l'opérateur d'aplatissement. Plutôt que de créer un canevas initial fondé uniquement sur la taille de canevas de la première image, l'opérateur de mosaïque crée un canevas assez grand pour contenir toutes les images (uniquement dans le sens positif). Par exemple, ici je ne définis même pas de canevas virtuel approprié, mais l'opérateur « [-mosaic](https://imagemagick.org/command-line-options/#mosaic) » déterminera la taille nécessaire d'un tel canevas pour contenir tous les calques d'images. |

  magick \( -page +5+10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -layers mosaic  mosaic.gif

[IM Output]
| _Depuis IM v6.3.6-2, l'opérateur « [-mosaic](https://imagemagick.org/command-line-options/#mosaic) » n'est qu'un alias de « [-layers](https://imagemagick.org/command-line-options/#layers) 'mosaic' ».

Ainsi, l'option « [-mosaic](https://imagemagick.org/command-line-options/#mosaic) » peut être vue comme un raccourci de la méthode « [-layers](https://imagemagick.org/command-line-options/#layers) » du même nom._
---|---
Notez que « [-mosaic](https://imagemagick.org/command-line-options/#mosaic) » et « [-flatten](https://imagemagick.org/command-line-options/#flatten) » créent tous deux un canevas partant de l'« origine », le pixel 0,0. Cela fait partie de la définition du « canevas virtuel » ou de la « page » d'une image, et de ce fait vous pouvez être sûr que l'image finale de ces deux opérateurs n'aura aucun décalage virtuel et que tout le canevas sera entièrement défini en données de pixels réelles. Notez aussi que « [-mosaic](https://imagemagick.org/command-line-options/#mosaic) » n'étendra le canevas que dans les directions positives (les bords inférieur ou droit), car les bords supérieur et gauche sont fixés à l'origine virtuelle. Cela signifie évidemment que « [-mosaic](https://imagemagick.org/command-line-options/#mosaic) » rognera toujours les images à décalage négatif… |

  magick \( -page -5-10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -mosaic  mosaic_clip.gif

[IM Output]

Fusion (Merge) - créer une nouvelle image de calque

L'opérateur « [-layers](https://imagemagick.org/command-line-options/#layers) **merge** » est presque identique aux opérateurs précédents et a été ajouté avec IM v6.3.6-2. Il crée uniquement une image de canevas juste assez grande pour contenir toutes les images données à leurs décalages respectifs. Comme la mosaïque (Mosaic), il étend aussi le canevas, mais pas seulement dans le sens positif : également dans le sens négatif. En clair, cela signifie que vous n'avez pas à vous soucier du rognage, du décalage ni d'autres aspects lors de la fusion de calques. Toutes les images seront fusionnées relativement les unes aux autres. La sortie n'inclut pas l'origine et ne garantit pas qu'elle fasse partie du canevas étendu. Ainsi, la sortie d'une fusion de calques peut comporter un « décalage de calque » qui peut être positif ou négatif. Autrement dit… la fusion de calques (Merge) fusionne des calques pour produire une nouvelle image de calque. Par conséquent, si vous ne voulez pas de ce décalage une fois terminé, vous voudrez probablement inclure un opérateur « [+repage](https://imagemagick.org/command-line-options/#repage) » avant l'enregistrement final. Par exemple, voici le même jeu de calques que celui déjà utilisé… |

  magick \( -page +5+10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -layers merge  +repage layers_merge.gif

[IM Output]
Comme vous le voyez, l'image est juste assez grande pour contenir toutes les images placées relativement les unes aux autres, tandis que j'ai écarté le décalage résultant relatif à l'origine du canevas virtuel. Cette préservation de la position relative sans rognage ni espace superflu est ce qui rend cette variante si puissante. Réessayons en donnant à une image un décalage négatif… |

  magick \( -page -5-10  balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( -page +62+50 present.gif \)   \( -page +10+55 shading.gif \)  \
          -background dodgerblue  -layers merge  +repage layers_merge_2.gif

[IM Output]
Comme vous le voyez, le « balloon » n'a pas été rogné : il a simplement été éloigné des autres afin de préserver sa distance relative à eux. Bien sûr, l'opérateur « [+repage](https://imagemagick.org/command-line-options/#repage) » dans les exemples ci-dessus supprime le décalage absolu du canevas virtuel dans l'image finale, ne préservant que le placement relatif des images. Le décalage a été supprimé parce que les navigateurs web ont souvent du mal avec les décalages d'image, et surtout les décalages négatifs, sauf s'ils font partie d'une animation GIF. Mais si je n'avais pas supprimé ce décalage, toutes les images resteraient à leur emplacement correct sur le canevas virtuel au sein de l'image de calque unique générée, ce qui permet de continuer à traiter et à ajouter d'autres images à l'image fusionnée. On utilise généralement une couleur « [-background](https://imagemagick.org/command-line-options/#background) » de « None » pour rendre transparentes les zones inutilisées de l'image fusionnée. Appliquée à une seule image, la fusion de calques remplacera toute transparence de l'image par la couleur d'arrière-plan opaque, mais préservera la taille originale de l'image ainsi que ses éventuels décalages ; la taille du canevas virtuel de l'image peut toutefois être ajustée au « meilleur ajustement » de la taille et du décalage de cette image. Le but initial de l'opérateur était de permettre aux utilisateurs de fusionner plus facilement plusieurs images déformées en un ensemble unifié, quel que soit le décalage de chaque image. Par exemple, lors de l'alignement de photos pour former un « panorama » plus grand. Vous pourriez simplement partir d'une image de base centrale non déformée (sans décalage) et utiliser cet opérateur pour superposer les autres images autour de ce point de départ (à l'aide de décalages négatifs ou positifs), après les avoir alignées et déformées pour correspondre à cette image centrale. Pour d'autres exemples d'utilisation de cet opérateur en déformant des images afin d'aligner des points de contrôle communs, voir Cube photo isométrique 3D et Boîte en perspective 3D. Un autre exemple d'utilisation de cet opérateur est la génération d'une simple série de photos qui se chevauchent.

L'opération "-layers trim-bounds" peut servir à garantir que toutes
les images obtiennent un décalage positif sur un canevas de taille minimale,
tout en conservant leurs positions relatives, et sans réellement fusionner
les calques en une seule image finale.

Cela permet ensuite d'effectuer d'autres traitements sur les images avant
leur fusion effective, par exemple placer d'autres images relativement à ce
groupe d'images en consultant les limites du canevas virtuel obtenu.

Toutefois, si les images comportent une transparence, il est probablement
judicieux de rogner d'abord cette transparence, d'où l'usage idéal…

  -alpha set -bordercolor none -border 1x1 -trim -layers trim-bounds

Cela minimise les calques d'images, y compris toutes les zones transparentes
des données d'image réelles, tout en garantissant que tout tienne sur un
canevas virtuel (positif) valide de taille minimale.

Coalescence (Coalesce) - une superposition progressive

L'opérateur d'image « [-layers](https://imagemagick.org/command-line-options/#layers) **coalesce** » (ou son raccourci « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) ») est en réalité conçu pour convertir des animations GIF en une séquence d'images. Pour des exemples, voir Coalescence des animations. Il est cependant très étroitement lié à « [-flatten](https://imagemagick.org/command-line-options/#flatten) » et a des effets très utiles pour les images multi-calques à cet égard. Par exemple, utiliser la coalescence (Coalesce) sur une seule image fera exactement le même travail que l'aplatissement (Flatten) avec une couleur « [-background](https://imagemagick.org/command-line-options/#background) » de « None » ou « Transparency ». Autrement dit, cela « remplira » le canevas de l'image avec des pixels transparents. |

  magick \( -page 100x100+5+10 balloon.gif \) -layers coalesce  coalesce_canvas.gif

[IM Output]
Face à une image composée de plusieurs calques, la coalescence (Coalesce) peut servir à générer une « superposition progressive » de l'image. Mais pour cela, il faut prendre quelques précautions afin de désactiver toute gestion d'« animation GIF » par l'opérateur.

   magick \( -page 100x100+5+10 balloon.gif \)   \( -page +35+30 medical.gif \)  \
           \( --page +62+50       present.gif \)   \( -page +10+55 shading.gif \)  \
           -set dispose None  -coalesce  miff:- |\
     montage - -frame 4 -tile x1 -geometry +2+2 \
             -background none -bordercolor none  coalesce_none.gif

[IM Output]

Dans ce qui précède, nous « [-set](https://imagemagick.org/command-line-options/#set) » tous les réglages « [-dispose](https://imagemagick.org/command-line-options/#dispose) » à « [None](anim_basics.html#none) ». Cela indique en pratique à « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) » de superposer simplement chaque trame par-dessus le résultat des superpositions précédentes. Résultat : la première image n'est qu'un « remplissage » du canevas de l'image, avec un arrière-plan transparent. L'image suivante est l'image précédente avec ce calque superposé. Et ainsi de suite. Un aplatissement « progressif » de la séquence d'images. La dernière image de la séquence sera donc identique à un « [-flatten](https://imagemagick.org/command-line-options/#flatten) » normal avec un arrière-plan transparent. On obtient un effet tout à fait différent en utilisant un réglage « [-dispose](https://imagemagick.org/command-line-options/#dispose) » de « [Background](anim_basics.html#background) ». Dans ce cas, « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) » se contentera de « remplir » le canevas de chaque image, comme s'il s'agissait d'images totalement séparées !

  magick \( -page 100x100+5+10 balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( --page +62+50       present.gif \)   \( -page +10+55 shading.gif \)  \
          -set dispose Background  -coalesce  miff:- |\
    montage - -frame 4 -tile x1 -geometry +2+2 \
            -background none -bordercolor none  coalesce_bgnd.gif

[IM Output]

Notez toutefois que, contrairement à l'aplatissement (Flatten), à la mosaïque (Mosaic) ou à la fusion (Merge), l'opérateur « [-coalesce](https://imagemagick.org/command-line-options/#coalesce) » n'utilise pas le réglage de composition alpha « [-compose](https://imagemagick.org/command-line-options/#compose) » courant. Il n'utilise qu'une méthode de composition « [Over](compose.html#over) », car c'est ce qu'exige la gestion des animations GIF. L'utilisation de différentes méthodes « [-compose](https://imagemagick.org/command-line-options/#compose) » avec les opérateurs de superposition plus classiques fait l'objet de la série d'exemples suivante.

Méthodes de composition et superposition

Les trois méthodes de superpositionaplatissement (Flatten), mosaïque (Mosaic) et fusion (Merge) — utilisent le réglage « [-compose](https://imagemagick.org/command-line-options/#compose) » pour déterminer la méthode de composition employée pour superposer chaque image de la séquence. On peut donc voir ces fonctions comme un opérateur « [-composite](https://imagemagick.org/command-line-options/#composite) » multi-images, avec la possibilité de définir un canevas « [-background](https://imagemagick.org/command-line-options/#background) » initial d'une couleur donnée. Toutefois, utiliser autre chose que la composition alpha « Over » par défaut demande réflexion avant application, sous peine de résultats inattendus. Vous devrez peut-être aussi réfléchir à l'effet de la couleur « [-background](https://imagemagick.org/command-line-options/#background) » qu'utilisent ces opérateurs pour générer un canevas de départ, sur lequel chaque image (y compris la première) est composée. Par exemple, plaçons chaque image successive sous les images précédentes à l'aide d'un « [DstOver](compose.html#dstover) »… |

  magick \( -page 100x100+5+10 balloon.gif \)   \( -page +35+30 medical.gif \)  \
          \( --page +62+50       present.gif \)   \( -page +10+55 shading.gif \)  \
          -background none  -compose DstOver  -flatten  flatten_dstover.gif

[IM Output]
Ici, l'arrière-plan a été rendu transparent, sinon vous ne verriez que le canevas d'arrière-plan dans le résultat, car toutes les autres images auraient été placées « sous » ce canevas initial ! Cela offre un moyen d'« effacer » une image avec une couleur donnée, comme montré dans Canevas dimensionnés à une image existante. Voici un exemple plus concret. Plutôt que de superposer les images avec le canevas d'arrière-plan en premier, ce qui est maladroit et peu naturel dans certaines situations de traitement d'image, vous pouvez simplement générer les images de haut en bas, ou du premier plan vers l'arrière-plan. |

  magick rose: -repage +10+10 \
          \( +clone -background black -shadow 60x3+5+5 \) \
          \( granite: -crop 100x80+0+0 +repage \) \
          -background none  -compose DstOver -layers merge layer_dstover.gif

[IM Output]
Chacune des trois premières lignes génère un calque, la dernière ligne fusionnant tous les calques sous les calques précédents, inversant ainsi l'ordre.

Comme vous le voyez, le traitement d'image ci-dessus a été plus simple et plus propre que ce que l'on voit d'ordinaire pour la génération d'ombres, simplement en glissant chaque image sous la précédente (avec un canevas de départ transparent)

J'aurais bien sûr tout aussi facilement pu inverser (Reverse) la liste d'images. |

  magick rose: -repage +10+10 \
          \( +clone -background black -shadow 60x3+5+5 \) \
          \( granite: -crop 100x80+0+0 +repage \) \
          -reverse -layers merge layer_reverse.gif

[IM Output]
Cependant, rappelez-vous que cela ne fait que réordonner les images existantes et n'affecte pas le « canevas d'arrière-plan de départ » que créent les méthodes de superposition. Les méthodes de composition peuvent aussi servir à produire des effets intéressants. Par exemple, si vous dessinez trois cercles, en les superposant avec la méthode de composition « Xor », vous obtenez un symbole insolite et d'apparence complexe, pour un effort minimal. |

  magick -size 60x60 \
          \( xc:none -fill blue   -draw 'circle 21,39 24,57' \) \
          \( xc:none -fill red    -draw 'circle 39,39 36,57' \) \
          \( xc:none -fill green  -draw 'circle 30,21 30,3'  \) \
          -background none  -compose Xor   -flatten  flatten_xor.png

[IM Output]

Layers Composite - fusionner deux listes de calques

Avec IM v6.3.3-7, la méthode « [-layers](https://imagemagick.org/command-line-options/#layers) » « **Composite** » a été ajoutée, permettant de composer deux ensembles d'images totalement distincts. Pour le faire 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 destination et où commence la liste d'images source superposée. Mais c'est la seule véritable complication de cette méthode. Fondamentalement, chaque image de la première liste est composée avec l'image correspondante de la seconde, fusionnant ainsi les deux listes. La seconde liste peut être positionnée globalement par rapport à la première à l'aide d'un décalage de géométrie, tout comme avec un opérateur composite normal (voir plus haut). La gravité est aussi appliquée en utilisant la taille de canevas de la première image pour les calculs. En plus de ce « décalage global », le décalage virtuel individuel de chaque image est également préservé, à mesure que chaque paire d'images est composée. Un cas particulier est aussi géré. Si l'une des listes d'images ne contient qu'une seule image, celle-ci sera composée avec toutes les images de l'autre liste. Dans ce cas également, ce sont les métadonnées d'image (comme les cadences d'animation) de la liste la plus grande qui seront conservées, même si ce n'est pas le côté destination de la composition.
Cet opérateur de superposition est plus généralement employé lors de la composition de deux animations, que l'on peut considérer comme une sorte de liste d'images superposées dans le temps. Pour cette raison, il est mieux illustré dans la section Modifications d'animation des exemples. Voir donc Composition alpha multi-images pour plus de détails.


Manipulation des calques d'images

Superposer plusieurs images à l'aide des divers opérateurs de calques ci-dessus est une technique très polyvalente. Elle permet de travailler individuellement sur un grand nombre d'images, puis de les combiner toutes en un ensemble unifié une fois terminé. Jusqu'ici, nous avons montré diverses manières de fusionner (composer ou superposer) plusieurs images de multiples façons. Je propose ici quelques exemples plus concrets de la manière d'exploiter ces techniques.

Superposition de vignettes

Vous pouvez aussi utiliser cette technique pour fusionner plusieurs vignettes de diverses manières complexes. Ici, j'ajoute un bord adouci aux images au fur et à mesure que vous les lisez et les positionnez ; vous pouvez ainsi générer une composition d'images plutôt réussie, sur un canevas pavé.

  magick -page +5+5    holocaust_tn.gif \
          -page +80+50  spiral_stairs_tn.gif \
          -page +40+105 chinese_chess_tn.gif \
          +page \
          -alpha Set -virtual-pixel transparent \
          -channel A -blur 0x10  -level 50,100% +channel \
          \( -size 200x200 tile:tile_fabric.gif -alpha Set \) -insert 0 \
          -background None -flatten  overlap_canvas.jpg

[IM Output]

Positionnement calculé des images.

Le décalage du canevas virtuel (page) peut être défini de nombreuses façons. Plus précisément, vous pouvez « [-set](https://imagemagick.org/command-line-options/#set) » cet attribut par image, et même calculer un emplacement différent pour chaque image. Par exemple, ici je lis un grand ensemble d'images (de petites icônes, toutes de même taille) et je les dispose en cercle.

  magick {balloon,castle,eye,eyeguy,ghost,hand_point,medical}.gif \
          {news,noseguy,paint_brush,pencil,present,recycle}.gif \
          {shading,skull,snowman,storm,terminal,tree}.gif \
          \
          -set page '+%[fx:80*cos((t/n)*2*pi)]+%[fx:80*sin((t/n)*2*pi)]' \
          \
          -background none -layers merge +repage image_circle.png

[IM Output]

La clé de l'exemple ci-dessus est l'opération « [-set](https://imagemagick.org/command-line-options/#set) page » qui utilise l'indice d'image normalisé (l'expression FX « t/n ») pour créer une valeur de 0,0 à un peu moins de 1,0 pour chaque image. Cette valeur est ensuite convertie pour positionner l'image (par angle) sur un cercle de 80 pixels de rayon, à l'aide des expressions FX comme échappement de pourcentage. La position calculée est celle du coin supérieur gauche de l'image (et non de son centre, bien que ce soit un ajustement simple), qui est ensuite fusionnée (Merge) pour générer une nouvelle image. Le positionnement se fait sans se soucier du caractère positif ou négatif du décalage, ce qui fait la force de l'opérateur de superposition Merge. Autrement dit, nous avons généré une nouvelle image de toutes les images telles qu'elles se situent les unes par rapport aux autres. Le « [+repage](https://imagemagick.org/command-line-options/#repage) » final supprime le décalage négatif résultant de l'image de calque fusionnée, car il n'est plus nécessaire et peut poser problème lors de l'affichage de l'image obtenue. Notez que la première image (la plus à droite dans le résultat) est superposée sous toutes les autres. Si vous voulez que la superposition soit vraiment cyclique, de sorte que la dernière image passe sous cette première, il faudra peut-être diviser cette première image en deux et placer sa moitié supérieure à la fin de la séquence, pour que la moitié supérieure de la première image se superpose à la dernière image, tandis que sa moitié inférieure reste sous la deuxième image. Cette technique est puissante, mais elle ne peut positionner les images qu'à un décalage entier. Si vous avez besoin d'un positionnement d'images plus précis au sous-pixel, les images devront être déformées (translatées) vers l'emplacement sous-pixel exact plutôt que d'ajuster simplement leur décalage virtuel.

Positions calculées de manière incrémentale

Vous pouvez accéder à certains attributs d'image d'autres images à l'aide d'expressions FX, tout en définissant l'attribut des images au fur et à mesure de leur traitement. Cela signifie que vous pouvez définir l'emplacement de chaque image relativement à la position calculée de l'image précédente. Par exemple, ceci fixe la position de chaque image à droite de l'image précédente. C'est-à-dire la position de l'image précédente plus sa largeur.

  magick rose: netscape: granite: \
          \
          +repage -set page '+%[fx:u[t-1]page.x+u[t-1].w]+0' \
          \
          -background none -layers merge +repage append_diy.png

[IM Output]

Chaque image est ajoutée à l'emplacement de l'image précédente, en consultant cet emplacement et en y ajoutant la largeur de cette image. Cet emplacement précédent venait en fait tout juste d'être calculé, à mesure qu'IM parcourait chaque image en fixant l'attribut « page » (décalage virtuel). Le résultat est un équivalent « fait maison » de l'opérateur d'assemblage, à partir duquel vous pouvez développer vos propres variantes. Notez que la séquence entière est en réalité décalée de « u[-1].w », défini lors du calcul de position de la première image. Cela devrait être la largeur de la dernière image de la séquence d'images courante. Ce déplacement global est cependant jeté par le « [+repage](https://imagemagick.org/command-line-options/#repage) » final. Vous pouvez utiliser quelques calculs supplémentaires pour lui faire ignorer ce décalage, mais ce n'est pas nécessaire ci-dessus. | _Lorsque vous utilisez un indice d'image tel que « u[t] », tous les sélecteurs d'image « u », « v » et « s » référencent la même image, selon l'« [index] » donné. Il est donc préférable d'utiliser « u » (la première image, ou la zéroième) comme aide-mémoire de ce comportement d'indexation (et au cas où cela changerait).

Pour plus d'informations, voir FX, l'opérateur d'image fait maison._
---|---
Voici un autre exemple. Chaque image est décalée par rapport à l'image précédente, en utilisant à la fois la position et la largeur de cette image, afin de calculer un assemblage avec chevauchement.

magick font_[0-9].gif \
        -set page '+%[fx:u[t-1]page.x+u[t-1].w-8]+%[fx:u[t-1]page.y+4]' \
        -background none -layers merge +repage append_offset.gif

[IM Output]

Cette capacité à accéder aux attributs d'autres images inclut aussi les données de pixels d'autres images. Cela signifie que vous pourriez créer une image spéciale où les valeurs de couleur représentent les « positions mappées » des autres images. Bien sûr, cette image de « mappage » serait elle aussi positionnée et devrait être retirée avant d'effectuer la superposition. L'utilité de créer de telles images de « position mappée » est une autre question. Ce n'est qu'une possibilité de plus.

Positionnement en deux étapes des images

Vous pouvez simplifier votre traitement d'image en le séparant en deux étapes. Une étape peut servir à générer, déformer, positionner et enjoliver les images, avec une étape finale pour les fusionner toutes. Par exemple, créons des vignettes Polaroid à partir des images originales plus grandes de Photo Store, en traitant chacune individuellement (ce qui garde cet aspect séparé et simple).

  center=0   # Start position of the center of the first image.
             # This can be ANYTHING, as only relative changes are important.

  for image in ../img_photos/[a-m]*_orig.jpg
  do

    # Add 70 to the previous images relative offset to add to each image
    #
    center=`magick xc: -format "%[fx: $center +70 ]" info:`

    # read image, add fluff, and using centered padding/trim locate the
    # center of the image at the next location (relative to the last).
    #
    magick -size 500x500 "$image" -thumbnail 240x240 \
            -set caption '%t' -bordercolor Lavender -background black \
            -pointsize 12  -density 96x96  +polaroid  -resize 30% \
            -gravity center -background None -extent 100x100 -trim \
            -repage +${center}+0\!    MIFF:-

  done |
    # read pipeline of positioned images, and merge together
    magick -background skyblue   MIFF:-  -layers merge +repage \
            -bordercolor skyblue -border 3x3   overlapped_polaroids.jpg

[IM Output]

Le script ci-dessus semble compliqué, mais ne l'est pas vraiment. Il génère simplement chaque vignette dans une boucle, tout en complétant au centre (à l'aide d'Extent) et en rognant (Trim) chaque image de sorte que le « centre » de l'image se trouve à un emplacement connu sur le canevas virtuel. Il pourrait en fait calculer cette position, mais cela pourrait nécessiter des fichiers temporaires ; il est donc préférable de s'assurer qu'elle est à un emplacement bien connu, pour toutes les images. L'image est ensuite translatée (à l'aide d'un opérateur « [-repage](https://imagemagick.org/command-line-options/#repage) » relatif, voir Décalages de canevas), de sorte que chaque image générée se trouve exactement 60 pixels à droite de la précédente. Autrement dit, le centre de chaque image est espacé d'une distance fixe, quelle que soit la taille réelle de l'image, qui a pu changer en raison des rapports d'aspect et des rotations. L'autre astuce majeure de ce script est que, plutôt que d'enregistrer chaque « image de calque » dans un fichier temporaire, vous pouvez simplement écrire l'image dans un tube au format de fichier MIFF:. Une méthode connue sous le nom de flux d'images MIFF. Cela fonctionne parce que le format de fichier « MIFF: » permet de concaténer simplement plusieurs images en un seul flux de données, tout en préservant toutes les métadonnées des images, comme leur décalage de canevas virtuel. Cette technique constitue un bon point de départ pour de nombreux autres scripts. Les images peuvent être générées ou modifiées, et la taille et la position finales peuvent être calculées de la manière de votre choix. Un autre exemple est le script « [hsl_named_colors](../static/img/scripts/hsl_named_colors) » qui prend la liste des couleurs nommées d'ImageMagick et les trie en un tableau de ces couleurs dans l'espace colorimétrique HSL. Vous pouvez en voir la sortie dans Spécification des couleurs. Parmi les autres possibilités…

  • Utiliser n'importe quel type de vignette (ou autre enjolivure), ou simplement utiliser directement une petite vignette brute.
  • Générer les images de sorte que la première soit centrée et que les autres soient disposées à gauche et à droite sous cette première, comme une pyramide.
  • Positionner les images en arcs, cercles et spirales, en les plaçant à des coordonnées X et Y précises les unes par rapport aux autres. Par exemple : PhD Circle, Sunset Flower, Fibonacci Spiral.
  • Positionner les images selon leur couleur. Par exemple : Book Covers.
  • Positionner les images par heure de la journée ou heure de soumission. Par exemple : Year of Sunsets

En somme, vous disposez d'une liberté totale dans le positionnement des images sur le canevas virtuel, et vous pouvez ensuite simplement laisser IM déterminer la taille finale du canevas nécessaire pour contenir toutes les images.

Épingles sur une carte

Voici un exemple typique de superposition : placer des épingles colorées sur une carte, à des emplacements précis. [IM Output] À gauche se trouve une image d'« épingle ». La pointe de l'épingle est à la position +18+41. J'ai aussi une image de Carte de Venise et je veux placer une épingle à divers points de la carte. Par exemple, « Accademia » est située à la position en pixels +160+283. Pour aligner l'épingle sur cette position, il faut soustraire l'emplacement de la pointe de l'épingle de la position sur la carte. Cela produit un décalage de +142+242 pour notre image d'« épingle ». Voici le résultat, avec des images superposées

  magick map_venice.jpg    -page +142+242 push_pin.png \
          -flatten  map_push_pin.jpg

[IM Output]

Cet exemple provient d'une discussion sur le forum d'IM, Layering Images with Convert. Automatisons cela davantage. Nous avons un fichier listant les emplacements et couleurs de chaque épingle à placer sur la carte. Le nom d'emplacement dans le fichier n'est pas utilisé ; ce n'est qu'un commentaire de référence sur la position en pixels indiquée.

[Data File]

Lisons ce fichier texte pour créer des « épingles » dans une boucle.

  pin_x=18  pin_y=41

  cat map_venice_pins.txt |\
    while read x y color location; do

      [ "X$x" = "X#" ] && continue   # skip comments in data

      x=$(( x - pin_x ))    # magick x,y to pin image offsets
      y=$(( y - pin_y ))

      # magick 'color' to settings for color modulate (hue only)
      # assumes a pure 'red' color for the original push pin
      mod_args=$(
         magick xc:$color -colorspace HSL txt: |
           tr -sc '0-9\012' ' ' |\
             awk 'NR==1 { depth=$3 }
                  NR==2 { hue=$3;
                          print  "100,100,"  100+200*hue/depth
                        }'; )

      # re-color and position the push pin
      magick push_pin.png -repage +${x}+${y} -modulate $mod_args miff:-

    done |\
      # read pipeline of positioned images, and merge together
      magick map_venice.jpg  MIFF:-  -flatten  map_venice_pins.jpg

[IM Output]

Notez qu'il suppose que la couleur d'origine de l'épingle est le rouge (dont la teinte est 0) et utilise l'opérateur Modulate pour la recolorer en d'autres couleurs, avec les calculs de mise à l'échelle appropriés. Notez que l'argument modulate pour un changement de teinte sans effet est 100, avec un cycle sur une valeur de 200 (une sorte de pseudo-pourcentage). FUTUR : déformer la carte en perspective, ajuster la taille de l'épingle selon la « profondeur » sur la carte, calculer le changement de position de l'épingle dû à la distorsion, et l'« épingler » sur la carte déformée. Ce qui précède utilisait une méthode connue sous le nom de flux d'images MIFF, chaque image étant générée individuellement dans une boucle, puis « redirigée » vers la commande de « superposition » pour générer l'image finale. La méthode alternative (couramment utilisée dans les scripts PHP) consiste à recourir à une technique de « commande générée », où un script shell génère une longue commande « magick » à exécuter. Les scripts de Animations de déformation d'image emploient cette technique. Les deux méthodes évitent d'avoir à générer des images temporaires.

Calques d'ombres

Gérer correctement les effets d'ombre semi-transparents dans un ensemble d'images qui se chevauchent est en réalité bien plus difficile qu'il n'y paraît. Se contenter de superposer des photos avec leurs ombres fait appliquer les ombres deux fois. C'est-à-dire que deux ombres qui se chevauchent deviennent très sombres, alors qu'en réalité elles ne se superposent pas tout à fait de la même manière que les images qui se chevauchent. Les diverses parties de l'image devraient être simplement ombrées ou non ombrées. Autrement dit, une ombre ne devrait être appliquée qu'une seule fois à une partie donnée de l'image. Vous ne devriez pas obtenir de zones plus sombres, sauf si vous avez deux sources de lumière distinctes, ce qui peut compliquer encore les choses. Tomas Zathurecky < tom @ ksp.sk > a relevé le défi de gérer les effets d'ombre dans des images en calques et a développé une technique d'accumulateur d'images pour résoudre le problème. Fondamentalement, nous devons ajouter chaque image au bas de la pile une par une. Lorsque nous ajoutons une nouvelle image, l'ombre de toutes les images précédentes doit assombrir la nouvelle image avant qu'elle ne soit ajoutée à la pile. Cependant, seule l'ombre tombant sur la nouvelle image doit être ajoutée. Les ombres ne tombant pas sur la nouvelle image doivent être ignorées jusqu'à plus tard, lorsqu'elles tomberont sur une autre image, ou sur l'arrière-plan (le cas échéant). Voici un exemple… |

  magick \
    \( holocaust_tn.gif -frame 10x10+3+3 \
          -background none  -rotate 5 -repage +0+0 \) \
    \
    \( spiral_stairs_tn.gif -frame 10x10+3+3 \
          -background none -rotate -15 -repage -90+60 \) \
    \( -clone 0   -background black -shadow 70x3+4+7 \
       -clone 1   -background black -compose DstATop -layers merge \
       -trim \) \
    \( -clone 2,0 -background none  -compose Over -layers merge \) \
    -delete 0--2 \
    \
    \( chinese_chess_tn.gif -frame 10x10+3+3 \
          -background none -rotate 20 -repage +60+90 \) \
    \( -clone 0   -background black -shadow 70x3+4+7 \
       -clone 1   -background black -compose DstATop -layers merge \
       -trim \) \
    \( -clone 2,0 -background none  -compose Over -layers merge \) \
    -delete 0--2 \
    \
    \( +clone -background black -shadow 70x3+4+7 \) +swap \
    -background none -compose Over -layers merge +repage \
    layers_of_shadows.png

[IM Output]
Le programme ci-dessus semble complexe, mais il est en réalité assez simple. La première image sert à amorcer une pile d'images en accumulation (indice d'image #0). Notez que nous aurions pu tout aussi bien commencer par un unique pixel transparent (« -size 1x1 xc:none »), si vous ne voulez pas utiliser cette première image pour initialiser la pile. Maintenant, pour ajouter une nouvelle image au bas de la pile, nous appliquons à chaque fois le même ensemble d'opérations…

  • On lit d'abord la vignette en mémoire, puis on lui applique les rotations et placements relatifs (éventuellement négatifs). Vous pourriez aussi appliquer d'autres opérations de mise en vignette à l'image à ce stade si vous le souhaitez, bien que pour cet exemple elles aient déjà été effectuées. La nouvelle image forme l'indice d'image #1.
  • Nous saisissons ensuite la pile d'images précédente (#0) et générons une ombre avec la couleur, le flou, le décalage et le pourcentage de lumière ambiante appropriés.
  • Cette ombre est superposée sur la nouvelle image (#1) de sorte que seule l'ombre tombant « [ATop](compose.html#atop) » la nouvelle image soit conservée. Nous appliquons aussi (facultativement) une opération de rognage (Trim) au résultat pour retirer l'espace supplémentaire ajouté par l'opération d'ombrage, formant ainsi l'image #2.
  • Il ne reste plus qu'à ajouter la nouvelle image (#2) à la pile d'images en accumulation (#0).
  • et à supprimer toutes les images de travail précédentes, sauf la dernière.

Pour ajouter d'autres images, il suffit essentiellement de répéter le bloc d'opérations ci-dessus. Une fois toutes les images ajoutées à la pile, il ne reste qu'à effectuer une opération d'ombrage normale sur la pile d'images accumulée, en retirant tout décalage d'image restant (que beaucoup de navigateurs web détestent). À l'aide de la fusion (Merge), je peux gérer automatiquement les décalages virtuels, en particulier négatifs, ce qui permet de placer simplement les images où l'on veut par rapport aux placements précédents. Cela facilite aussi l'application d'ombres, qui peuvent générer des images plus grandes avec des décalages négatifs, correctement.
Ce qui précède gère donc correctement les ombres d'images multi-calques, mais, si l'ombre est décalée, elle l'est en réalité de la même manière pour toutes les images ! Ce qui devrait réellement se produire, c'est que l'ombre devienne de plus en plus décalée et de plus en plus floue à mesure qu'elle tombe sur des images de plus en plus profondes dans la pile. Autrement dit, une image du sommet devrait projeter une ombre très floue sur l'arrière-plan, comparée à l'image la plus basse. C'est en réalité plus difficile à réaliser, car il faut non seulement suivre la pile d'images, mais aussi suivre le degré de « flou » qu'a pris l'ombre à mesure que la pile s'agrandit. Il vous faut donc réellement deux accumulateurs : la pile d'images (comme ci-dessus) et l'accumulation d'ombre, au fur et à mesure que nous ajoutons des images. Par exemple, voici le même ensemble d'images, mais avec des ombres qui deviennent plus floues avec la profondeur. |

  magick xc:none xc:none \
    \
    \( holocaust_tn.gif -frame 10x10+3+3 \
          -background none  -rotate 5 -repage +0+0 \) \
    \( -clone 1   -background black -shadow 70x0+0+0 \
       -clone 2   -background black -compose DstATop -layers merge \
       -clone 0   -background none  -compose Over    -layers merge \) \
    \( -clone 2,1 -background none  -compose Over    -layers merge \
                  -background black -shadow 100x2+4+7 \) \
    -delete 0-2 \
    \
    \( spiral_stairs_tn.gif -frame 10x10+3+3 \
          -background none -rotate -15 -repage -90+60 \) \
    \( -clone 1   -background black -shadow 70x0+0+0 \
       -clone 2   -background black -compose DstATop -layers merge \
       -clone 0   -background none  -compose Over    -layers merge \) \
    \( -clone 2,1 -background none  -compose Over    -layers merge \
                  -background black -shadow 100x2+4+7 \) \
    -delete 0-2 \
    \
    \( chinese_chess_tn.gif -frame 10x10+3+3 \
          -background none -rotate 20 -repage +60+90 \) \
    \( -clone 1   -background black -shadow 70x0+0+0 \
       -clone 2   -background black -compose DstATop -layers merge \
       -clone 0   -background none  -compose Over    -layers merge \) \
    \( -clone 2,1 -background none  -compose Over    -layers merge \
                  -background black -shadow 100x2+4+7 \) \
    -delete 0-2 \
    \
    \( -clone 1 -background black -shadow 70x0+0+0 \
       -clone 0 -background none -compose Over -layers merge \) \
    -delete 0-1 -trim +repage \
    layers_of_deep_shadows.png

[IM Output]
Regardez attentivement le résultat. Le décalage et le flou de l'ombre diffèrent selon les parties de l'image. Elle est très fine entre des images de calques adjacents, mais très épaisse lorsqu'elle tombe sur une image, ou même sur l'arrière-plan bien plus bas. Bien sûr, dans cet exemple, le décalage de l'ombre est probablement trop grand, mais le résultat paraît très réaliste et donne un meilleur sentiment de profondeur aux calques. Notez comme nous avons scindé l'opération d'ombrage en deux étapes. Lorsque nous appliquons l'ombre accumulée (indice d'image #1) à la nouvelle image (#2), nous n'ajoutons que le pourcentage de lumière ambiante, sans flou ni décalage (« 70x0+0+0 » ici). La nouvelle image est ensuite ajoutée à la pile d'images en accumulation (#0). Mais après avoir ajouté l'ombre de la nouvelle image (#2) directement à l'ombre accumulée (#1), là encore sans flou ni décalage, ce n'est qu'ensuite que nous floutons et décalons TOUTES les ombres pour former la nouvelle image d'ombre accumulée. Autrement dit, l'image d'ombre accumulée devient de plus en plus floue et décalée à mesure que la pile s'épaissit. Seule l'ombre des images plus profondes n'a pas accumulé l'effet autant. Ce programme sépare essentiellement l'application de l'ombre de l'accumulateur d'ombre incrémental. Cela vous permet de contrôler des choses comme…

  • Ombre réaliste (comme ci-dessus) : 70x0+0+0 et 100x2+4+7
  • Ombre constante (comme l'exemple de base) : 70x2+4+7 et 100x0+0+0
  • flou constant, mais décalage cumulatif : 70x2+0+0 et 100x0+4+7
  • décalage à la fois constant et progressif : 60x0+4+7 et 100x0+1+1
  • effet de lumière ambiante cumulatif : 80x0+0+0 et 95x2+4+7

La plupart d'entre eux sont probablement irréalistes, mais peuvent bien rendre dans d'autres situations. De plus, régler la couleur « -background » avant la composition « -compose ATOP » vous permettra de définir la couleur de l'ombre (en réalité une lumière ambiante colorée). Vous pouvez même utiliser une couleur différente pour l'ombre qui finit par tomber sur le calque d'arrière-plan final (le dernier réglage « -background black »), ou l'omettre entièrement pour donner l'impression que les images ne sont au-dessus d'aucun arrière-plan (c'est-à-dire flottant dans les airs). C'est extrêmement polyvalent.
Tomas Zathurecky a ensuite développé une autre méthode de gestion des ombres d'images en calques, en traitant une liste d'images en calques comme un tout. Quelque chose que je n'aurais moi-même pas cru possible. L'avantage de cette méthode est que vous pouvez traiter toute une liste d'images comme un tout, plutôt que d'avoir à accumuler une image à la fois et à répéter le même bloc d'opérations encore et encore. Revenons d'abord au problème plus simple de l'« ombre constante ». |

  magick \
    \( holocaust_tn.gif -frame 10x10+3+3 \
          -background none  -rotate 5 -repage +0+0 \) \
    \( spiral_stairs_tn.gif -frame 10x10+3+3 \
          -background none -rotate -15 -repage -90+60 \) \
    \( chinese_chess_tn.gif -frame 10x10+3+3 \
          -background none -rotate 20 -repage +60+90 \) \
    \
    -layers trim-bounds \
    \
    \( -clone 0--1 -dispose None -coalesce \
       -background black -shadow 70x2+4+7 \
       xc:none +insert null: +insert +insert xc:none \) \
    -layers trim-bounds -compose Atop -layers composite \
    \
    -fuzz 10% -trim \
    -reverse -background none -compose Over -layers merge +repage \
    coalesced_shadows.png

[IM Output]
Le premier bloc d'opérateurs ne fait que générer la liste d'images en calques. Il pourrait s'agir d'une boucle programmée à part, comme montré précédemment. L'opération commence par un « -layers trim-bounds », une opération de rognage aux limites qui étend le canevas virtuel de toutes les images de façon à les contenir toutes, et garantit aussi que tous les décalages soient positifs. Ceci est ensuite cloné, coalescé (Coalesce) et ombré pour créer une liste d'ombres progressive distincte. Nous pouvons maintenant utiliser la composition en calques pour fusionner les ombres et la liste d'images originale. La complication ici est qu'avant la fusion, nous devons non seulement ajouter une image marqueur « null: » spéciale pour diviser les deux listes, mais aussi ajouter une image vierge spéciale « xc:none » afin de décaler la liste d'ombres. Ainsi, chaque image d'ombre sera superposée « [ATop](compose.html#atop) » à l'image suivante de la liste originale. Il ne reste plus qu'à fusionner les images désormais correctement ombrées, du bas vers le haut (ordre inversé (Reverse)).
Gérer les « ombres profondes » requiert des calculs de calques. |

  magick \
    \( holocaust_tn.gif -frame 10x10+3+3 \
          -background none  -rotate 5 -repage +0+0 \) \
    \( spiral_stairs_tn.gif -frame 10x10+3+3 \
          -background none -rotate -15 -repage -90+60 \) \
    \( chinese_chess_tn.gif -frame 10x10+3+3 \
          -background none -rotate 20 -repage +60+90 \) \
    \
    \( -clone 0--1 \
       -set page '+%[fx:page.x-4*t]+%[fx:page.y-7*t]' -layers merge \) \
    -layers trim-bounds +delete \
    \
    \( -clone 0--1 \
       -set page '+%[fx:page.x-4*t]+%[fx:page.y-7*t]' \
            -dispose None -coalesce \
       -set page '+%[fx:page.x+4*t]+%[fx:page.y+7*t]' \
            -background black -shadow 70x2+4+7 \
       xc:none +insert null: +insert +insert xc:none \) \
    -layers trim-bounds -compose Atop -layers composite \
    \
    -fuzz 10% -trim \
    -reverse -background none -compose Over -layers merge +repage \
    coalesced_deep_shadows.png

[IM Output]
Vous pouvez voir le même ensemble de blocs qu'utilisé précédemment, mais avec des calculs bien plus compliqués pour définir le rognage aux limites initial, et calculer ensuite les décalages nécessaires à la « liste d'ombres progressive ». L'ombre ne devient toutefois pas plus floue avec la profondeur. | Ce qui précède sera bien plus simple avec la commande « magick » d'IMv7, qui permettrait d'utiliser des « calculs fx » directement dans l'argument de « -shadow » ; cela vous permettrait non seulement de calculer un décalage plus grand pour l'ombre avec la profondeur, mais aussi de rendre l'ombre plus floue avec la profondeur.
---|---

Positionnement d'images en perspective déformées

Aligner des images déformées peut être délicat, et je vais ici m'intéresser à l'alignement de telles images pour qu'elles coïncident à un emplacement bien précis. J'ai ici deux images qui mettent en évidence un point précis sur chacune.

[IM Output] [IM Output]

La seconde image est semi-transparente à 65 %, ce qui permet de la voir par transparence lorsqu'elle est composée sur l'image bleue, afin de vérifier si les points marqués s'alignent. Les points de contrôle marqués eux-mêmes sont aux coordonnées 59,26 (bleu) et 35,14 (rouge) respectivement. Si vous superposez simplement les deux images, vous pouvez juste soustraire les décalages et « composer » les deux images l'une sur l'autre, produisant un décalage de +24+12. |

  magick align_blue.png align_red.png -geometry +24+12 \
          -composite align_composite.png

[IM Output]
Notez que ce décalage pourrait être négatif ! Et c'est un point que nous traiterons sous peu. Cela ne fonctionne que parce que les coordonnées sont des coordonnées en pixels entières. Si les coordonnées correspondantes sont des emplacements sous-pixels (comme c'est typiquement le cas dans un montage photo), la simple composition ne fonctionnera pas. Elle ne fonctionnera pas bien non plus si une quelconque distorsion est en jeu (ce qui est également courant pour les images de la vie réelle). Et c'est le problème que nous allons explorer.
Lorsque vous déformez l'image, vous voudrez vous assurer que les deux pixels restent alignés. La meilleure façon d'y parvenir serait d'utiliser les points à aligner comme points de contrôle de distorsion. Cela garantira qu'ils sont positionnés correctement. |

  magick align_blue.png \
          \( align_red.png -alpha set -virtual-pixel transparent \
             +distort SRT '35.5,14.5  1 75  59.5,26.5' \
          \) -flatten  align_rotate.png

[IM Output]
Comme la distorsion génère une « image de calque » dotée d'un « décalage de canevas », vous ne pouvez pas simplement utiliser Composite pour superposer les images (trop bas niveau) ; il faut au contraire utiliser un opérateur d'aplatissement (Flatten), afin qu'il les positionne à l'aide du décalage généré par la distorsion. Notez que j'ai aussi ajouté une valeur de 0,5 aux coordonnées de « pixel ». C'est parce que les pixels ont une aire, alors que les points mathématiques n'en ont pas ; ainsi, si vous voulez aligner le centre d'un pixel, vous devez ajouter 0,5 à l'emplacement du « point » central au sein du pixel. Voir Coordonnées d'image et coordonnées de pixel pour plus d'informations. L'autre problème du cas ci-dessus était que l'image superposée était « rognée » par l'image de canevas d'arrière-plan bleue, exactement comme le fait l'opérateur Composite. Autrement dit, l'image « bleue » fournissait la « fenêtre de rognage » du résultat pendant la composition. Pour empêcher cela, nous utilisons plutôt la fusion de calques (Merge), qui calcule automatiquement un canevas « fenêtre » assez grand pour contenir toutes les images composées. |

  magick align_blue.png \
          \( align_red.png -alpha set -virtual-pixel transparent \
             +distort SRT '35.5,14.5  1 75  59.5,26.5' \
          \) -background none -layers merge +repage  align_rotate_merge.png

[IM Output]
Du fait de la « fusion », l'image aura un décalage « négatif » (afin de préserver les positions de calque des images). Pour afficher le résultat, j'ai dû jeter ce décalage, car de nombreux navigateurs ne gèrent pas les décalages négatifs dans les images. Je le fais avec « +repage » avant l'enregistrement de l'image finale. Si je devais poursuivre le traitement (sans afficher le résultat sur le web), je conserverais ce décalage (en retirant le « +repage »), afin que les positions des images restent à leur emplacement correct et connu pour un traitement ultérieur.
Les mêmes techniques que celles montrées ci-dessus s'appliqueraient aussi si vous réalisiez une distorsion plus complexe, telle qu'une perspective. |

  magick align_blue.png \
          \( align_red.png -alpha set -virtual-pixel transparent \
             +distort Perspective '35.5,14.5  59.5,26.5
                       0,0 32,4    0,%h 14,36    %w,%h 72,53  ' \
          \) -background none -layers merge +repage  align_perspective.png

[IM Output]
Le problème de cette technique est que vous positionnez la distorsion en perspective à l'aide d'un point de contrôle interne. C'est-à-dire un point à l'intérieur de l'image et 3 points autour du bord. Cela peut rendre difficile le contrôle de la forme réelle de la perspective, car un petit déplacement de l'un des points de contrôle peut faire bouger énormément le « coin libre ». Cette situation peut être pire encore si vous utilisez une grande liste de « points enregistrés » pour obtenir un « ajustement aux moindres carrés » plus exact du positionnement des images. Dans ce cas, le point qui vous intéresse peut n'être nulle part près de l'un des points de contrôle « enregistrés » utilisés pour déformer l'image. L'alternative consiste à simplement déformer l'image comme il le faut, puis à déterminer comment translater l'image résultante pour aligner les points qui nous intéressent. Pour que cela fonctionne, il nous faudra savoir comment le « point d'intérêt » s'est déplacé du fait de la distorsion. C'est un vrai problème lors de la distorsion et du positionnement d'images, en particulier d'images de la vie réelle. Par exemple, ici je déforme l'image en utilisant les quatre coins pour produire une forme de distorsion précise (supposément désirée), mais je n'essaierai pas d'aligner les points de contrôle à ce stade, je me contenterai d'appliquer la distorsion… |

  magick align_blue.png \
          \( align_red.png -alpha set -virtual-pixel transparent \
             +distort Perspective '0,0  10,12  0,%h 14,40
                               %w,0 68,6  %w,%h 63,48 ' \
          \) -background none -layers merge +repage  align_persp_shape.png

[IM Output]
Comme vous le voyez, si l'image rouge a bien été déformée, la position du point de contrôle rouge n'est nulle part près du point de contrôle bleu que nous voulons aligner. Vous ne pouvez pas simplement mesurer ces deux points, car le point rouge n'est probablement pas à une position pixel exacte, mais présentera un décalage sous-pixel. Nous devrons d'abord calculer exactement où se trouve le point rouge. Pour ce faire, nous pouvons réexécuter la distorsion ci-dessus avec le mode verbeux activé, afin d'obtenir les coefficients de mappage direct de la perspective. Ceux-ci peuvent ensuite servir au calcul décrit dans Distorsion par projection en perspective.

  magick align_red.png  -define distort:viewport=1x1  -verbose \
          +distort Perspective '0,0  10,12  0,%h 14,40
                                %w,0 68,6  %w,%h 63,48 ' null:

[IM Text]

Tout ce que nous voulons, ce sont juste les coefficients calculés utilisés par la distorsion. Nous n'avons donc pas besoin de l'image de destination ; nous jetons simplement la sortie à l'aide d'un format de fichier image « null: ». Nous indiquons aussi à la distorsion que la nouvelle image qu'elle génère ne fait qu'un pixel de taille, à l'aide d'une fenêtre de distorsion (Distort Viewport). Ainsi, elle effectue la préparation de la distorsion et le rapport verbeux, mais ne déforme ensuite qu'un unique pixel de « destination », qui est ensuite jeté. Cela peut faire gagner beaucoup de temps de traitement. En fait, si la distorsion n'utilisait pas les métadonnées de l'image source (nécessaires aux échappements de pourcentage « %w » et « %h ») dans ses calculs, nous n'aurions même pas besoin de l'image source « align_red.png ». Dans ce cas, nous aurions pu utiliser une seule image « null: » d'un pixel comme image d'entrée elle aussi. Nous ne nous intéressons pas non plus vraiment aux pixels virtuels, aux arrière-plans ni à quoi que ce soit d'autre pour cette étape de collecte d'informations, donc nul besoin de nous soucier de régler ces caractéristiques.
Maintenant que nous pouvons obtenir l'information de distorsion, nous devons extraire les 8 coefficients de perspective, des 3e et 4e lignes de la sortie. Ceux-ci peuvent ensuite servir à mapper le point de contrôle rouge vers sa nouvelle position déformée, et de là le soustraire du point de contrôle bleu, afin d'obtenir la quantité réelle de translation nécessaire pour aligner la coordonnée rouge marquée avec la coordonnée bleue.

  bluex=59; bluey=26
  redx=35; redy=14

  magick align_red.png  -verbose \
             +distort Perspective '0,0  10,12  0,%h 14,40
                               %w,0 68,6  %w,%h 63,48 ' null: 2>&1 |\
    tr -d "',"  |\
      awk 'BEGIN   { redx='"$redx"'+0.5;   redy='"$redy"+0.5';
                     bluex='"$bluex"'+0.5; bluey='"$bluey"'+0.5; }
           NR == 3 { sx=$1; ry=$2;  tx=$3; rx=$4; }
           NR == 4 { sy=$1; ty=$2;  px=$3; py=$4; }
           END { div =  redx*px + redy*py + 1.0;
                 dx = ( redx*sx + redy*ry + tx ) / div;
                 dy = ( redx*rx + redy*sy + ty ) / div;
                 printf "red point now at %f,%f\n", dx, dy;
                 printf "translate shape by %+f %+f\n", bluex-dx, bluey-dy; }'

[IM Text]

Ce qui précède utilisait le filtre de texte « tr » pour retirer les guillemets et virgules superflus de la sortie. Il utilise ensuite le programme « awk » pour extraire les coefficients et effectuer les calculs en virgule flottante requis pour « mapper vers l'avant » le marqueur rouge afin qu'il corresponde au marqueur bleu. Notez que j'ai de nouveau ajouté 0,5 aux « coordonnées de pixel » des points de contrôle pour garantir que c'est bien le centre du pixel qui est utilisé pour les calculs. Voir Coordonnées d'image et coordonnées de pixel. Maintenant que nous connaissons la quantité de translation requise par l'image déformée, nous avons deux manières d'ajouter cette translation à la distorsion. Soit en modifiant les coefficients de la projection en perspective en conséquence (pas facile). Soit en ajoutant simplement les quantités de translation à chacune des coordonnées de destination de l'original (très facile). Voici le résultat de la seconde méthode (ajout des translations aux coordonnées de destination)… |

  magick align_blue.png \
          \( align_red.png -alpha set -virtual-pixel transparent \
             +distort Perspective '0,0   31.408223,15.334305
                                   0,%h  35.408223,43.334305
                                   %w,0  89.408223, 9.334305
                                   %w,%h 84.408223,51.334305 ' \
          \) -background none -layers merge +repage  align_persp_move.png

[IM Output]
À droite, j'ai rogné et mis à l'échelle le résultat autour des points de contrôle pour montrer qu'ils sont parfaitement alignés ! |

  magick align_persp_shape.png -crop 19x19+50+17 +repage \
          -scale 500%   align_persp_shape_mag.png

[IM Output]
Comme vous le voyez, nous avons un alignement parfait des deux pixels, sans aucun débordement sous-pixel d'un côté ou de l'autre. Le moindre désalignement se traduirait par une coloration asymétrique de part et d'autre du pixel central. Cette mise à l'échelle montre même une légère différence asymétrique entre les côtés gauche et droit de la croix rouge, due à la distorsion en perspective. Voilà à quel point ce test au niveau du pixel est précis.
Un problème similaire mais plus simple est examiné dans Positionnement de texte à l'aide de Distort.


Evaluate-Sequence - méthodes directes de fusion multi-images

Les méthodes « [-evaluate-sequence](https://imagemagick.org/command-line-options/#evaluate-sequence) » sont conçues pour fusionner plusieurs images de même taille de façons très précises. À certains égards, c'est un mélange des opérateurs Evaluate et Function combinés aux techniques de composition multi-images vues plus haut. Beaucoup des méthodes proposées peuvent même être réalisées à l'aide des techniques normales de composition en calques multi-images, mais pas toutes. L'opérateur utilise les mêmes méthodes que « [-evaluate](https://imagemagick.org/command-line-options/#evaluate) », vous pouvez donc en obtenir la liste avec « -list Evaluate ». Certaines d'entre elles (comme « Mean » et « Medium ») ne sont toutefois réellement utiles qu'avec cet opérateur.

Moyenne (Average) de plusieurs images

En substance, l'ancien « -evaluate-sequence mean » comme le plus récent « [-evaluate-sequence](https://imagemagick.org/command-line-options/#evaluate-sequence) **mean** » créeront une moyenne de toutes les images fournies. Par exemple, voici une moyenne de l'image rose en utilisant toutes ses versions retournées horizontalement et verticalement. |

  magick rose: -flip rose: \( -clone 0--1 -flop \) \
          -evaluate-sequence mean  average.png

[IM Output]
Faire la moyenne de centaines d'images d'une même scène fixe peut servir à éliminer la plupart des effets transitoires, comme des personnes en mouvement, en les rendant moins visibles. Cependant, les zones qui subissent beaucoup d'effets transitoires peuvent conserver un « flou fantomatique » très difficile à supprimer. Comme les séquences vidéo sont notoirement bruitées lorsqu'on regarde les images individuelles, vous pouvez faire la moyenne de plusieurs trames consécutives, mais inchangées, pour produire un résultat bien plus propre et plus net. Matt Leigh, de l'Université d'Arizona, rapporte avoir utilisé cette technique pour améliorer la résolution d'images au microscope. Il prend plusieurs images de la même « cible », puis en fait la moyenne pour augmenter le rapport signal/bruit des résultats. Il suggère que d'autres pourraient aussi trouver cela utile à cette fin. Une alternative pour faire la moyenne de deux images est d'utiliser une opération d'image « composite -blend 50% », qui fonctionne avec deux images de tailles différentes. Voir l'exemple de Fondu de deux images ensemble pour plus de détails. Le forum de discussion d'IM a eu une discussion sur Averaging a sequence 10 frames at a time, afin de moyenner des milliers d'images sans saturer la mémoire de l'ordinateur (ce qui le rend très lent). En lien avec cela, et contenant des mathématiques pertinentes, il y a la discussion Don't load all images at once. Une autre alternative à « mean » est d'utiliser le plus récent opérateur Poly, qui peut pondérer chaque image individuellement.

Valeur max/min de plusieurs images

Les méthodes « Max » et « Min » obtiennent les valeurs maximales (plus claires) et minimales (plus sombres) d'une séquence d'images. Là encore, elles sont fondamentalement équivalentes à l'utilisation des méthodes de composition Lighten et Darken, mais avec plusieurs images. Avec un choix judicieux de couleur de canevas d'arrière-plan, vous pourriez utiliser l'opérateur d'aplatissement (Flatten) avec la méthode de composition équivalente. |

  magick rose: -flip rose: \( -clone 0--1 -flop \) \
          -evaluate-sequence max  max.png

[IM Output]
|

  magick rose: -flip rose: \( -clone 0--1 -flop \) \
          -evaluate-sequence min  min.png

[IM Output]
AVERTISSEMENT : il ne s'agit pas d'une sélection de pixels (par intensité), mais d'une sélection de valeurs. Cela signifie que l'image de sortie pourrait résulter en des valeurs rouge, verte et bleue individuelles provenant d'images différentes, produisant une nouvelle couleur ne figurant dans aucune des images d'entrée. Si vous avez besoin que les pixels soient sélectionnés par leur max/min d'intensité, voir la méthode de composition Lighten par intensité.

Pixel médian par intensité

« [-evaluate-sequence](https://imagemagick.org/command-line-options/#evaluate-sequence) **Median** » cherchera le pixel qui a l'intensité du pixel médian parmi toutes les images fournies. Autrement dit, pour chaque position, il collecte et trie l'intensité des pixels de chacune des images. Puis il choisit le pixel qui tombe au milieu de la séquence. Cela peut aussi servir d'alternative à la simple moyenne des pixels d'un ensemble d'images. On pourrait par exemple l'utiliser en combinant une image avec deux images « limites » supérieure et inférieure. Comme le pixel sera d'intensité médiane, vous obtiendrez soit le pixel de l'image originale, soit un pixel des images « limites ». Autrement dit, vous pouvez l'utiliser pour « écrêter » l'intensité de l'image originale. Étrange mais vrai. Pour un nombre pair d'images, c'est le pixel du côté le plus clair du milieu qui sera sélectionné. Ainsi, avec seulement deux images, cet opérateur sera équivalent à un « lighten par intensité » au niveau du pixel. Le point clé est que chaque pixel proviendra entièrement d'une seule image, trié par intensité. La couleur exacte de chaque pixel proviendra entièrement de l'une des images fournies, de sorte qu'aucune nouvelle couleur n'est générée. Par exemple, voici les pixels d'intensité médiane de l'image rose en utilisant toutes ses versions retournées horizontalement et verticalement. Notez que ce n'est pas aussi lisse, mais que cela peut donner des frontières nettes, car cela se fonde sur les intensités des pixels. |

  magick rose: -flip rose: \( -clone 0--1 -flop \) \
          -evaluate-sequence median  median.png

[IM Output]

Additionner plusieurs images

La méthode « Add » additionnera bien sûr simplement toutes les images ensemble.

  magick ... -evaluate-sequence add ...

Ce qui est une version plus rapide (plus directe) de l'utilisation de l'aplatissement (Flatten) pour composer en Plus toutes les images ensemble…

  magick ... -background black -compose plus -layers flatten ...

Attention : additionner des images de cette manière peut très facilement dépasser la plage quantique de l'image, qui peut de ce fait être « écrêtée », à moins d'utiliser une version HDRI d'IM. C'est pourquoi on utilise généralement plutôt une moyenne (Average, ou Mean), car cela divise toutes les images de façon égale pour garantir que l'image résultante ne soit pas écrêtée. Une autre alternative est d'utiliser le plus récent opérateur Poly, qui peut pondérer chaque image individuellement.

Soustraire plusieurs images

La méthode « Subtract » soustrait chaque image de la première. Du moins, c'est ce qu'elle devrait faire. En interne, les arguments sont inversés et elle soustrait les résultats précédents de l'image suivante. Arrggggg ! Cependant, en tirant parti d'une particularité de la méthode de composition Linear Burn, vous pouvez soustraire la deuxième image et les suivantes de la première. Fondamentalement, en négativant (Negate) toutes les images sauf la première, et en définissant un « white » (zéro négativé) comme couleur d'arrière-plan de départ, vous pouvez ensuite utiliser l'aplatissement (Flatten) pour soustraire toutes les images de la première.

  magick ...  \
         -negate \( -clone 0 -negate \) -swap 0 +delete \
         -compose LinearBurn -background white -flatten \
         ...

Multiplier/Diviser plusieurs images

« Multiply » et « Divide » sont acceptées comme méthodes par « [-evaluate-sequence](https://imagemagick.org/command-line-options/#evaluate-sequence) », mais elles produisent des résultats inattendus et étranges, car elles utilisent la valeur de couleur réelle des images plutôt que la valeur de couleur normalisée, tout comme le fait « [-evaluate](https://imagemagick.org/command-line-options/#evaluate) ». Résultat : l'échelle de la multiplication et de la division est trop grande. Cela pourrait être classé comme un bogue. En attendant, mieux vaut utiliser la méthode « flatten » équivalente pour Multiply, qui, elle, fonctionne comme prévu.

  magick ... -background white -compose multiply -layers flatten ...

Poly - fusionner plusieurs images à l'aide d'un polynôme

Étroitement lié à « [-evaluate-sequence](https://imagemagick.org/command-line-options/#evaluate-sequence) », et spécifiquement à la méthode « mean » (moyenne d'images), se trouve l'opérateur « [-poly](https://imagemagick.org/command-line-options/#poly) » (ajouté à IM v6.8.0-5). Cet opérateur reçoit une liste de deux nombres pour chaque image en mémoire : l'un fournit un poids multiplicatif pour chaque image, l'autre un exposant de puissance pour chaque image. Cela permet de fusionner une liste d'images comme si chaque image était la variable d'entrée d'une équation polynomiale. Les valeurs de couleur de chaque image sont traitées comme si elles étaient une valeur normalisée de 0 à 1. Pour chaque paire de valeurs, la couleur de l'image (normalisée) est d'abord élevée au second exposant « puissance de », puis pondérée (multipliée) par le premier nombre. Si l'exposant est « 1 », la valeur est simplement multipliée par la pondération donnée. En revanche, si l'exposant est « 0 », le poids devient la valeur finale, produisant l'addition d'une constante de couleur normalisée (valeur de 0,0 à 1,0). Une image d'un seul pixel peut être fournie dans la séquence d'images courante et peut servir à ajouter une couleur précise, avec une valeur de couleur normalisée différente pour chaque canal (à l'aide d'un poids et d'un exposant de 1,0). Vous pouvez aussi fournir une image « NULL: » (ou toute autre image sans intérêt) et utiliser un exposant de 0,0. Cela n'ajoutera que le facteur de pondération donné en tant que constante. L'image finale est générée à partir de la première image (et de sa taille et autres métadonnées), tout comme avec l'opérateur FX fait maison. Par exemple… |

  magick rose: granite: null: -poly '1,1 2,1 -1.0,0' poly_rose.png

[IM Output]
Ceci prend un « rose: » (inchangé, avec un poids de 1 et une puissance de 1), y ajoute deux fois les valeurs de couleur de l'image « granite: » (poids=2), puis soustrait une valeur de 1 à l'aide d'une image « null: », avec un exposant de 0 (l'entrée image est ignorée) et une valeur de pondération de -1,0. L'image résultante est équivalente à…

rose + 2.0*granite - 1.0

ou

rose + 2.0*(granite-0.5)

Autrement dit, l'image rose reçoit une superposition de texture de granite bruitée (avec un biais gris à 50 %). C'est en fait exactement comme un effet d'éclairage de composition « [Hard_Light](compose.html#hardlight) » très fort, mais avec une pondération très explicite de la superposition de granite. La différence clé de cette méthode par rapport aux autres opérations multi-images est la capacité de pondérer chaque image individuellement, tout en effectuant tous les calculs en une seule opération de traitement d'image, sans avoir besoin d'images intermédiaires supplémentaires. Cela évite tout arrondi quantique, écrêtage ou autre effet sur les résultats finaux, dans une version non HDRI d'ImageMagick. (Voir Effets quantiques.) Cela peut par exemple servir à effectuer une moyenne pondérée d'un grand nombre d'images, comme moyenner de plus petits groupes d'images, puis moyenner ces groupes ensemble.