Exemples ImageMagick -- Création de canevas
Les canevas sont utilisés par ImageMagick comme image de départ pour dessiner, comme arrière-plan sur lequel superposer des images comportant des zones transparentes, voire simplement dans le cadre du traitement d'image en général. Ils peuvent être d'une couleur unie, présenter une plage de couleurs, ou même être une mosaïque d'une image plus petite. Nous examinons ici quelques-unes seulement des méthodes permettant de générer toute une gamme d'images de canevas.
Canevas de couleur unie
Génération directe
Générer un canevas d'une couleur et d'une taille données est très simple. Il suffit de spécifier "[-size](https://imagemagick.org/command-line-options/#size)" (avec "1x1" par défaut si aucune taille n'est donnée), puis d'utiliser "canvas:" pour générer un canevas de la couleur indiquée. Si aucune couleur n'est spécifiée, un canevas 'white' (blanc) est généré. Par exemple… ici je génère un canevas de couleur 'khaki'. |
magick -size 100x100 canvas:khaki canvas_khaki.gif
![[IM Output]](../static/img/canvas/canvas_khaki.gif)
Plus couramment, on utilise une forme abrégée (et plus traditionnelle) "xc:" (qui signifiait "X Constant Image"). C'est généralement celle que j'emploie. Par exemple, voici une image utilisant la couleur X window 'wheat'. |
magick -size 100x100 xc:wheat canvas_wheat.gif
![[IM Output]](../static/img/canvas/canvas_wheat.gif)
En recourant à quelques Modificateurs de lecture d'image astucieux, on peut spécifier une image de canevas de couleur unie sous forme d'un seul argument. Cette technique permet de fournir une image de canevas 'xc' d'une taille et d'une couleur données comme unique argument « image d'entrée » à de nombreux scripts ImageMagick. |
magick 'xc:Salmon[100x100!]' canvas_salmon.gif
| Le '!' est nécessaire car les nombres sont des valeurs de redimensionnement ; sans lui, vous n'obtiendriez pas la taille demandée si elle n'est pas carrée.
---|---
![[IM Output]](../static/img/canvas/canvas_salmon.gif)
Si vous avez déjà créé un canevas mais qu'il vous en faut un d'une autre couleur, vous pouvez remplacer cette couleur à l'aide de l'opérateur "[-opaque](https://imagemagick.org/command-line-options/#opaque)". |
magick canvas_khaki.gif -fill tomato -opaque khaki canvas_tomato.gif
![[IM Output]](../static/img/canvas/canvas_tomato.gif)
Vous pouvez même prélever un seul pixel dans une image existante et l'agrandir à la taille de canevas voulue. Nous utilisons "[-scale](https://imagemagick.org/command-line-options/#scale)" pour un redimensionnement simple et rapide de ce pixel unique. Ici, nous prélevons une couleur de rose dans l'image intégrée "rose:". |
magick rose: -crop 1x1+40+30 +repage -scale 100x100\! canvas_rose_red.gif
Créer une image de même taille
| L'une des techniques les plus fondamentales, quand on utilise ImageMagick, consiste à générer un canevas de la même taille qu'une image existante. On y parvient en convertissant cette image existante en le canevas voulu tout en préservant la taille d'origine de l'image. En général, ce n'est pas seulement la taille de l'image qu'il faut préserver, mais aussi l'ensemble de ses métadonnées : les étiquettes, les commentaires, les profils colorimétriques, les délais temporels, ainsi que la compression et la profondeur d'enregistrement. Ces métadonnées peuvent être importantes si vous voulez annoter ces informations sur le canevas fraîchement vidé, ou si vous comptez superposer l'image d'origine sur le nouveau canevas et devez conserver ces informations. Naturellement, IM offre un grand nombre de façons de faire cela, le plus souvent comme effet secondaire de diverses opérations sur les images. Seules quelques-unes indiquent clairement leur usage pour ramener une image à une couleur unie. À gauche se trouve une image de test… Ne vous souciez pas de la manière dont je l'ai réellement générée, cela n'a pas d'importance pour l'exercice. Je l'ai conçue pour contenir toute une gamme de couleurs, de transparences et d'autres caractéristiques, afin précisément de mettre IM à rude épreuve lors de son utilisation. Si les commandes utilisées pour générer cette image vous intéressent vraiment, vous pouvez consulter le script spécial "generate_test" que j'emploie pour la créer. | ![]() |
|---|---|
Superposer une couleur donnée
Depuis IM v6.4.2-1, vous pouvez utiliser "[+level-colors](https://imagemagick.org/command-line-options/#level_colors)" avec une seule couleur et sans virgule pour définir toutes les couleurs. |
magick test.png -alpha Opaque +level-colors Sienna color_levelc.gif
![[IM Output]](../static/img/canvas/color_levelc.gif)
Notez l'emploi de l'opérateur "[-alpha](https://imagemagick.org/command-line-options/#alpha)" pour amener la transparence à un état utile avant (ou après) l'ajout de la couleur. Vous pourriez aussi utiliser "-channel All" afin que le canal de transparence soit lui aussi défini par l'opération de réinitialisation de la couleur. Une autre technique plus ancienne consiste à utiliser "[-colorize](https://imagemagick.org/command-line-options/#colorize)" pour superposer la couleur de remplissage avec une valeur entièrement opaque. Toutefois, avant IM v6.7.9, cela ne modifiait pas le canal alpha de l'image d'origine ; il est donc conseillé de désactiver d'abord le canal alpha avec "[-alpha](https://imagemagick.org/command-line-options/#alpha) [Off](masking.html#alpha_off)", ou de le rendre opaque avec "[-alpha](https://imagemagick.org/command-line-options/#alpha) [Opaque](masking.html#alpha_off)", même si vous obtiendriez le même résultat sans cela. |
magick test.png -alpha off -fill Chocolate -colorize 100%
color_colorize.gif
| Notez que "[-alpha](https://imagemagick.org/command-line-options/#alpha) [Off](masking.html#alpha_off)" (ou son ancien équivalent "[-alpha off](https://imagemagick.org/command-line-options/#matte)") ne fait que désactiver le canal alpha. Si vous le réactivez ensuite avec On, le canal alpha d'origine (qui a été préservé) sera restauré. Avant IM v6.7.9, l'alpha était préservé lors de l'utilisation de "[-colorize](https://imagemagick.org/command-line-options/#colorize)".
---|---
![[IM Output]](../static/img/canvas/color_colorize.gif)
Depuis IM v6.4.3-0, vous pouvez utiliser l'opérateur "[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)" pour fixer un point à la couleur voulue et la faire se propager sur toute l'image, avec pratiquement n'importe quelle méthode de coloration qu'il propose (voir Points de couleur épars ci-dessous). |
magick test.png -alpha Off \
-sparse-color Voronoi '0,0 Peru' color_sparse.gif
![[IM Output]](../static/img/canvas/color_sparse.gif)
Une méthode plus générale consiste à utiliser "[-draw](https://imagemagick.org/command-line-options/#draw)" pour réinitialiser directement toutes les couleurs de l'image courante à la couleur "[-fill](https://imagemagick.org/command-line-options/#fill)" en vigueur. |
magick test.png -fill Tan -draw 'color 0,0 reset' color_reset.gif
![[IM Output]](../static/img/canvas/color_reset.gif)
C'était la méthode recommandée dans la version 5 d'ImageMagick.
Le principal reproche adressé à toutes les méthodes « simples » ci-dessus est qu'aucune ne ramène simplement l'image à la couleur "[-background](https://imagemagick.org/command-line-options/#background)" en vigueur. La série de méthodes suivante fait appel à la Composition alpha pour forcer divers opérateurs à remplacer l'image par la couleur voulue. Ces techniques à images multiples fonctionnent avec les opérateurs qui utilisent "[-compose](https://imagemagick.org/command-line-options/#compose)". Par exemple, vous pouvez utiliser "[-flatten](https://imagemagick.org/command-line-options/#flatten)" (voir l'exemple Aplatir sur l'arrière-plan), qui crée un canevas à partir de la couleur "[-background](https://imagemagick.org/command-line-options/#background)". |
magick test.png -background Wheat \
-compose Dst -flatten color_flatten.gif
![[IM Output]](../static/img/canvas/color_flatten.gif)
Ce qui précède utilise la méthode de composition '[Dst](compose.html#Dst)' pour ne lire que le canevas d'arrière-plan et ignorer les couleurs de pixels de l'image d'origine. Si vous voulez seulement récupérer les métadonnées de l'image d'origine (comme les commentaires ou les étiquettes), mais remplacer l'image elle-même par un canevas d'une couleur et d'une taille données, alors l'opérateur "[-extent](https://imagemagick.org/command-line-options/#extent)" (voir Extent, ajustement direct de la taille d'image) est peut-être la meilleure solution. Là encore, la méthode de composition '[Dst](compose.html#Dst)' est utilisée pour lui faire ignorer les données de pixels de l'image d'origine, de sorte à n'employer que la couleur "[-background](https://imagemagick.org/command-line-options/#background)". |
magick test.png -background LemonChiffon \
-compose Dst -extent 100x100 color_extent.gif
![[IM Output]](../static/img/canvas/color_extent.gif)
Vous pouvez aussi utiliser "[-border](https://imagemagick.org/command-line-options/#border)" (voir Ajouter une bordure), en employant "[-bordercolor](https://imagemagick.org/command-line-options/#bordercolor)" comme source de la couleur. |
magick test.png -bordercolor Khaki \
-compose Dst -border 0 color_border.gif
![[IM Output]](../static/img/canvas/color_border.gif)
Cette dernière méthode présente l'avantage supplémentaire de permettre aussi d'agrandir légèrement le canevas de l'image par rapport à la taille de l'image d'origine. | La méthode de génération de canevas "[-border](https://imagemagick.org/command-line-options/#border)" ne fonctionne pas avec les versions d'IM antérieures à la 6.1.4. Auparavant, l'arrière-plan généré par l'opérateur "[-border](https://imagemagick.org/command-line-options/#border)" n'était pas une simple couleur unie, mais un canevas noir entouré de la couleur de bordure. Pas très utile.
---|---
Une méthode de génération de canevas plus souple (mais très lente) était fournie par l'opérateur "[FX, opérateur DIY](transform.html#fx)". Vous devrez également désactiver le canal de transparence de l'image d'entrée, car par défaut "[-fx](https://imagemagick.org/command-line-options/#fx)" ne touche pas au canal de transparence. |
magick test.png -alpha off -fx Gold color_fx_constant.gif
![[IM Output]](../static/img/canvas/color_fx_constant.gif)
L'opérateur "[-fx](https://imagemagick.org/command-line-options/#fx)" vous permet même de faire un peu d'arithmétique de couleur. Par exemple, que diriez-vous d'un or assombri de 70 %… |
magick test.png -alpha off -fx "Gold*.7" color_fx_math.gif
![[IM Output]](../static/img/canvas/color_fx_math.gif)
Toutes les méthodes ci-dessus peuvent remplir non seulement avec une couleur entièrement opaque, mais aussi avec des couleurs semi-transparentes. Il est cependant conseillé de s'assurer au préalable que l'image possède un canal de transparence. Ici, par exemple, nous créons un canevas avec un rouge semi-transparent. Mais une fois superposé sur l'arrière-plan « bleuté » des pages web, on obtient une couleur rose-violacé délavée. |
magick test.png -alpha set -fill '#FF000040' -draw 'color 0,0 reset' \
color_semitrans.png
![[IM Output]](../static/img/canvas/color_semitrans.png)
Notez également que lorsque vous utilisez l'opérateur "[-fx](https://imagemagick.org/command-line-options/#fx)" avec la transparence, vous devrez définir "[-channel](https://imagemagick.org/command-line-options/#channel)" pour modifier les quatre canaux de couleur 'RGBA'.
Vider une image avec une couleur prélevée
Vider une image en utilisant une couleur de l'image d'origine est également possible, quoique délicat. C'est une technique utile lorsque vous voulez employer un pixel précis comme « couleur d'arrière-plan ». Par exemple, le pixel 0,0 est un choix courant.
Dans les exemples suivants, je vais sélectionner des couleurs sur divers pixels de l'image rose intégrée (montrée à gauche) tout en vidant l'image. La méthode la plus évidente (bien que lente) consiste simplement à utiliser l'"[opérateur FX, DIY](transform.html#fx)" pour sélectionner le pixel à employer pour le vidage de couleur. |
magick rose: -fx 'p{0,0}' color_pick_fx.png
![[IM Output]](../static/img/canvas/color_pick_fx.png)
On peut toutefois accélérer cela en ne sélectionnant le pixel qu'une seule fois. Pour ce faire, on utilise la formule fx comme argument de Sparse Color. Cela peut sembler moins simple, mais c'est bien plus rapide. |
magick rose: -sparse-color voronoi '0,0 %[pixel:p{40,30}]'
color_pick_sparse.png
![[IM Output]](../static/img/canvas/color_pick_sparse.png)
Une autre méthode, plus complexe, consiste à découper ce pixel unique et à le disposer en mosaïque sur toute l'image, à l'aide des techniques décrites en détail plus loin dans Mosaïque avec une image déjà en mémoire |
magick rose: \( +clone -crop 1x1+64+22 -write MPR:pixel +delete \) \
-fill mpr:pixel -draw 'color 0,0 reset' \
color_pick_draw.png
magick rose: -set option:distort:viewport '%wx%h+0+0' \
-crop 1x1+10+25 +repage -distort SRT 0 \
color_pick_distort.png
Autres techniques de canevas
Il existe bien d'autres façons de générer des canevas de couleurs très précises, mais elles sont plutôt obscures. Aussi, sans commentaires abondants, il pourrait ne pas être évident de comprendre ce que vous faites réellement lorsque vous relirez votre script IM des mois ou des années plus tard. Je ne recommande pas ces techniques, mais elles sont utiles à connaître si vous utilisez des versions plus anciennes et moins souples d'IM. Canevas noir. Traditionnellement, vous pouvez créer un canevas noir en utilisant "-threshold", puis en désactivant le canal de transparence.
magick test.png -threshold 100% -alpha off black_threshold.png
Fournir à l'opérateur "-level" le même argument pour les points 'black' et 'white' produira le même effet.
magick test.png -level 100%,100% -alpha off black_level.png
L'opérateur "-fx" offre une manière plus évidente de créer un canevas noir en ramenant tous les pixels à zéro. Vous devrez toutefois aussi réinitialiser le canal alpha pour le rendre entièrement opaque.
magick test.png -fx 0 -alpha off black_fx.png
Cette version avec "-evaluate" devrait cependant être plus rapide, en particulier sur les grandes images.
magick test.png -evaluate set 0 -alpha off black_evaluate.png
Vous pouvez aussi détourner l'opérateur "-gamma" pour rendre une image entièrement noire.
magick test.png -gamma 0 -alpha off black_gamma.png
Une méthode moins évidente consiste à « postériser » l'image avec trop peu de niveaux de couleur, ce qui aboutit à l'emploi d'une seule couleur, le noir. |
magick test.png -posterize 1 -alpha off black_posterize.png
Opérateur alpha. Vous pouvez rendre l'image entièrement transparente, puis en 'extract' (extraire) le masque, à l'aide de l'opérateur
magick test.png -alpha transparent -alpha extract black_alpha.png
Canevas blanc. La méthode traditionnelle utilise là encore "-threshold". La valeur doit cependant être un nombre négatif, afin d'être sûr que toutes les couleurs seront mappées vers le blanc, dans toutes les versions d'IM.
magick test.png -threshold -1 -alpha off white_threshold.png
Fournir à l'opérateur "-level" le même argument pour les points 'black' et 'white' produira le même effet.
magick test.png -level -1,-1 -alpha off white_level.png
Vous pouvez bien sûr définir les valeurs des pixels directement à l'aide de l'opérateur "-fx".
magick test.png -fx 1.0 -alpha off white_fx.png
Cette version avec "-evaluate" devrait cependant être plus rapide, en particulier sur les grandes images.
magick test.png -evaluate set 100% -alpha off white_evaluate.png
Ou bien inversez (negate) une autre méthode de génération de canevas noir. |
magick test.png -posterize 1 -alpha off -negate white_posterize.png
Opérateur alpha. Vous pouvez rendre l'image entièrement opaque (sans transparence), puis en 'extract' (extraire) le masque, à l'aide de l'opérateur
magick test.png -alpha opaque -alpha extract white_alpha.png
Canevas transparent. Le canevas le plus important que vous voudrez probablement générer à partir d'une image existante est un canevas transparent. Vous pouvez ensuite dessiner et ajouter des éléments sur ce canevas, le mettre exactement comme vous le voulez, puis le superposer sur l'image d'origine. La méthode la plus rapide et la plus simple consiste simplement à demander à IM de vider directement l'image jusqu'à la transparence, à l'aide de l'opérateur "-alpha transparent" (ajouté en IM v6.4.3-7).
magick test.png -alpha transparent trans_alpha.png
Cependant, comme il s'agit d'un ajout très récent, il n'est probablement pas encore largement disponible. ![[IM Output]](../static/img/canvas/trans_alpha.png)
Nous pouvons créer un canevas 'noir' entièrement transparent à l'aide de l'opérateur de composition alpha 'Clear', avec n'importe quelle image de superposition (ici un seul pixel "null:"), car elle sera ignorée.
magick test.png null: -alpha set -compose Clear -composite -compose Over \
trans_compose.png
Ici, nous utilisons l'opérateur "-draw matte" pour remplacer la valeur du canal matte (transparence) par la valeur de transparence du réglage "-fill" en vigueur. Dans ce cas, on la rend entièrement transparente.
magick test.png -alpha set -fill none -draw 'matte 0,0 reset'
color_matte.png
Nous pouvons aussi faire cela plus directement avec l'opérateur "-fx".
magick test.png -alpha set -channel A -fx 0 +channel trans_fx.png
Naturellement, cette version avec "-evaluate" devrait être plus rapide, en particulier sur les grandes images.
magick test.png -alpha set -channel A -evaluate set 0 +channel \
trans_evaluate.png
Une autre façon de rendre simplement l'image entièrement transparente est d'utiliser "-threshold", mais en limitant là encore ses effets au seul canal de transparence.
magick test.png -channel A -threshold -1 +channel trans_threshold.png
En réalité, dans ce cas nous traitons mathématiquement un canal 'matte', en utilisant threshold pour le régler à sa valeur maximale plutôt qu'à zéro comme nous l'avons fait avec l'opérateur "-fx". C'est pourquoi un '-1' a été utilisé ci-dessus, plutôt que quelque chose comme 101%'. Dans beaucoup des résultats d'images ci-dessus, les couleurs RGB d'origine de l'image sont toujours présentes ; elles ont simplement été rendues transparentes. Par exemple, ici nous lisons l'une des images ci-dessus et demandons à IM de désactiver le canal matte/alpha de l'image afin de rendre les couleurs de nouveau visibles. |
magick trans_fx.png -alpha off trans_fx_alpha_off.jpg
Notez cependant que tous les formats de fichier image ne préservent pas — et que très peu d'opérations sur les images le font — les couleurs RGB partiellement transparentes qui subsistent dans l'image résultante. ![[IM Output]](../static/img/canvas/trans_fx_alpha_off.jpg)
Comme mentionné auparavant, et cela mérite d'être répété, beaucoup des méthodes ci-dessus reposent sur le fait que l'image possède déjà un canal alpha. Si ce n'est pas le cas, ajoutez-en un avec "[-alpha](https://imagemagick.org/command-line-options/#alpha) [On](masking.html#alpha_on)", mais dans ce cas autant utiliser directement l'opérateur "[-alpha](https://imagemagick.org/command-line-options/#alpha) Transparent". Voir les exemples sur Contrôler la transparence des images. Coloration diverse de canevas. Hormis l'usage d'une couleur donnée, seul l'opérateur "-gamma" est réellement assez souple pour générer un canevas de n'importe quelle couleur primaire ou secondaire. En gros, vous utilisez 0 pour annuler un canal et -1 pour maximiser les valeurs d'un canal. Par exemple, ici je génère un canevas jaune… |
magick test.png -gamma -1,-1,0 -alpha off yellow_gamma.png
![[IM Output]](../static/img/canvas/yellow_gamma.png)
Depuis IM v6.4.2, vous pouvez aussi utiliser l'opérateur "[+level](https://imagemagick.org/command-line-options/#level)" pour attribuer un niveau de gris donné à tous les canaux de couleur. |
magick test.png +level 40%,40% -alpha off grey_level.png
Dégradés de couleur
Comme vous l'avez vu ci-dessus, on peut créer assez facilement des canevas de couleurs unies. Mais parfois, on veut quelque chose de plus intéressant. L'un des opérateurs de création d'image les plus utiles est "gradient:". Par exemple… |
magick -size 100x100 gradient: gradient.jpg
![[IM Output]](../static/img/canvas/gradient.jpg)
Comme vous pouvez le constater, par défaut "gradient:" crée une image blanche en haut et noire en bas, avec un ombrage gris progressif et régulier sur toute la hauteur de l'image. Mais il n'est pas obligé de s'agir uniquement d'un dégradé en niveaux de gris : vous pouvez aussi générer un dégradé de couleurs différentes en spécifiant soit une seule couleur, soit les deux.
magick -size 100x100 gradient:blue gradient_range1.jpg
magick -size 100x100 gradient:yellow gradient_range2.jpg
magick -size 100x100 gradient:green-yellow gradient_range3.jpg
magick -size 100x100 gradient:red-blue gradient_range4.jpg
magick -size 100x100 gradient:tomato-steelblue gradient_range5.jpg
Remarquez que lorsqu'une seule couleur est donnée, la seconde couleur sera soit 'white', soit 'black', selon celle qui produit la plus grande distance colorimétrique par rapport à la couleur donnée. Ainsi 'blue' produit un dégradé 'blue-white', tandis que 'yellow' génère un dégradé 'yellow-black'. Le dégradé 'red-blue' présente une bande de couleurs violettes beaucoup plus sombre au milieu. Cet assombrissement est dû à l'emploi de l'espace colorimétrique sRGB non linéaire, plus sombre, surtout avec des couleurs primaires prononcées. Voir Traiter des images réelles pour plus de détails. | _"gradient:" ne comprend actuellement que les représentations de couleur de l'espace colorimétrique sRGB. Vous ne pouvez donc pas l'utiliser pour générer un dégradé « violet » plus vif et plus correct à partir de couleurs 'red-blue' dans un espace colorimétrique LAB linéaire.
Cela signifie aussi que vous ne pouvez pas générer de dégradés « arc-en-ciel » multicolores en utilisant l'espace colorimétrique HSV.
Vous pouvez toutefois « bricoler » de tels dégradés assez simplement. Voir Dégradés dans d'autres espaces colorimétriques ci-dessous.
---|---
| _Les dégradés ne peuvent actuellement pas être spécifiés sous d'autres angles ni faire intervenir plus de deux couleurs. Cependant, comme cette capacité fait partie intégrante des dégradés SVG, cette situation évoluera probablement, avec une amélioration majeure des options de dégradé.
---|---
Parmi les dégradés particulièrement réussis, on peut citer… |
magick -size 10x120 gradient:snow-navy gradient_ice-sea.jpg
magick -size 10x120 gradient:gold-firebrick gradient_burnished.jpg
magick -size 10x120 gradient:yellow-limegreen gradient_grassland.jpg
magick -size 10x120 gradient:khaki-tomato gradient_sunset.jpg
magick -size 10x120 gradient:darkcyan-snow gradient_snow_scape.jpg
![[IM Output]](../static/img/canvas/gradient_snow_scape.jpg)
| _Depuis IM v6.3.1, l'algorithme utilisé pour générer les dégradés produit désormais des couleurs horizontalement uniformes, de sorte que tous les pixels de chaque ligne de l'image se voient attribuer la même couleur. Autrement dit, une couleur par ligne.
Avant cette version, l'opérateur "gradient:" fonctionnait en ignorant la largeur de l'image et en attribuant simplement l'incrément de couleur suivant, ligne par ligne, du coin supérieur gauche vers le coin inférieur droit de l'image.
En conséquence, le dégradé était un dégradé essentiellement vertical, comme il l'est aujourd'hui, mais pas parfait. En général, ce fait n'avait d'importance que dans des cas particuliers, comme les images de test, et pour une utilisation dans le Mappage d'image.
_
---|---
Notez que le comportement des dégradés peut être affecté par ces defines :
Dégradés radiaux
Depuis IM v6.4.4, vous pouvez également générer des images de dégradé radial de manière similaire. |
magick -size 100x100 radial-gradient: rgradient.jpg
![[IM Output]](../static/img/canvas/rgradient.jpg)
Notez que le dégradé est centré au milieu de l'image générée et que son diamètre est réglé pour s'ajuster à la plus grande des dimensions X ou Y de l'image. Ainsi, si la taille de l'image n'est pas carrée, vous obtiendrez un dégradé radial « rogné ». |
magick -size 100x60 radial-gradient: rgradient_clip.jpg
![[IM Output]](../static/img/canvas/rgradient_clip.jpg)
Cela vous permet de générer facilement un dégradé radial carré, du centre vers un coin, en agrandissant l'un des côtés d'un facteur 1,42 (racine carrée de 2), puis en le rognant. |
magick -size 100x142 radial-gradient: \
-gravity center -crop 100x100+0+0 rgradient_crop.jpg
![[IM Output]](../static/img/canvas/rgradient_crop.jpg)
Les couleurs du dégradé lui-même suivent les mêmes conventions que le générateur d'image linéaire bien plus ancien "[gradient:](#gradient)".
magick -size 100x100 radial-gradient:blue rgradient_range1.jpg
magick -size 100x100 radial-gradient:yellow rgradient_range2.jpg
magick -size 100x100 radial-gradient:green-yellow rgradient_range3.jpg
magick -size 100x100 radial-gradient:red-blue rgradient_range4.jpg
magick -size 100x100 radial-gradient:tomato-steelblue rgradient_range5.jpg
Dégradés avec transparence
Depuis IM v6.2.9-8, l'opérateur de création d'image "gradient:" (et plus tard "radial-gradient:") comprend l'utilisation de couleurs transparentes et semi-transparentes. |
magick -size 100x100 gradient:none-firebrick gradient_transparent.png
![[IM Output]](../static/img/canvas/gradient_transparent.png)
| _Avant ImageMagick 6.5.4-7, les dégradés impliquant une transparence totale (comme le dernier exemple) produisaient généralement un halo noir.
Ce qui se passait, c'est que le dégradé généré allait de la couleur donnée à la couleur spéciale 'none', c'est-à-dire le noir transparent. Par conséquent, les couleurs tendaient vers un noir semi-transparent avant de devenir totalement transparentes.
La solution à ce problème consistait à générer un dégradé de transparence, puis à le colorer avec la couleur souhaitée._
---|---
|
magick -size 100x100 gradient:none-black \
-fill firebrick -colorize 100% gradient_trans_colorize.png
Dégradés par ajustement d'histogramme
Vous pouvez créer un dégradé non linéaire en appliquant une forme d'ajustement d'histogramme à un dégradé linéaire. Par exemple, vous pouvez utiliser une fonction Sigmoidal Contrast pour créer un dégradé d'aspect plus naturel. |
magick -size 100x100 gradient: -sigmoidal-contrast 6,50% \
gradient_sigmoidal.jpg
![[IM Output]](../static/img/canvas/gradient_sigmoidal.jpg)
Ce type de dégradé est particulièrement adapté à la génération de Photos superposées, car il supprime les changements brusques de dégradé au début de la région de recouvrement.
Dégradés Evaluate/Function
Vous pouvez également utiliser l'opérateur Evaluate et l'opérateur Function associé pour modifier un simple dégradé linéaire. |
magick -size 100x100 gradient: -evaluate cos 0.5 -negate \
gradient_cosine.jpg
![[IM Output]](../static/img/canvas/gradient_cosine.jpg)
Ou allez encore plus loin en créant un pic parabolique doux au centre du dégradé linéaire. |
magick -size 100x100 gradient: -function Polynomial -4,4,0 \
gradient_peak.jpg
![[IM Output]](../static/img/canvas/gradient_peak.jpg)
Ou encore un motif en bandes ou ondulé… |
magick -size 100x100 gradient: -function sinusoid 4,-90 \
gradient_bands.jpg
![[IM Output]](../static/img/canvas/gradient_bands.jpg)
Ces deux opérateurs étroitement liés vous permettent tous deux de modifier des images et des dégradés à partir de courbes sinusoïdales, de polynômes, de fonctions mathématiques logarithmiques et de puissance. Consultez Evaluate Math Functions et Function, Multi-Argument Evaluate pour davantage d'exemples.
Dégradés déformés
Dégradé pivoté
Bien que la méthode '[Barycentric](#barycentric)' de Sparse Color (voir ci-dessous) offre un moyen pratique de générer des dégradés sous n'importe quel angle, si votre IM est plus ancien que la version 6.4.3-0, vous devrez peut-être recourir à d'autres méthodes pour générer un dégradé diagonal ou pivoté. Par exemple, en augmentant la taille de l'image de dégradé (en la multipliant par la racine carrée de 2, soit 1,42), puis en la faisant pivoter de 45 degrés et en la rognant à sa taille finale, vous pouvez créer un dégradé diagonal. |
magick -size 142x142 gradient: -rotate -45 \
-gravity center -crop 100x100+0+0 +repage \
gradient_diagonal.jpg
![[IM Output]](../static/img/canvas/gradient_diagonal.jpg)
Depuis IM v6.3.5, vous disposez d'un moyen bien plus rapide et simple de générer un dégradé pivoté en utilisant une distorsion SRT. Par exemple, voici un dégradé de 100 pixels pivoté de 60 degrés dans une image de 100x100 pixels. |
magick -size 100x100 gradient: -distort SRT 60 gradient_srt.jpg
![[IM Output]](../static/img/canvas/gradient_srt.jpg)
Cela utilise le réglage par défaut Virtual Pixel, Edge pour garantir que l'image entière est couverte par le dégradé demandé. Vous pouvez également utiliser le réglage expert Distort Viewport pour mapper un dégradé sur une image plus grande, par exemple pour un usage dans Photos superposées.
Déformation de dégradés
Mais vous pouvez utiliser les mêmes méthodes de distorsion pour faire bien plus que de simples rotations. Le dégradé peut aussi être tordu… |
magick -size 100x100 gradient: -swirl 180 gradient_swirl.jpg
![[IM Output]](../static/img/canvas/gradient_swirl.jpg)
Vous pouvez remapper le dégradé en une forme trapézoïdale. |
magick -size 100x100 gradient: -rotate -90 \
-distort Perspective '0,0 40,0 99,0 59,0 0,99 -10,99 99,99 109,99' \
gradient_trapezoid.jpg
![[IM Output]](../static/img/canvas/gradient_trapezoid.jpg)
Ou enroulez le dégradé en arcs et en cercles à l'aide de l'opérateur de distorsion générale… |
magick -size 100x100 gradient: -distort Arc '180 0 50 0' \
gradient_arc.jpg
magick -size 100x100 gradient: -distort Arc '360 0 50 0' \
gradient_circle.jpg
![[IM Output]](../static/img/canvas/gradient_circle.jpg)
Cela dit, le nouveau "[radial-gradient:](#radial-gradient)" est probablement la méthode la plus simple pour générer ces dégradés. Un dégradé très utile mais plus difficile à générer est le dégradé d'angle polaire. La forme exacte de ce dégradé dépend de si le dégradé doit être centré sur une image de taille paire ou sur une image de taille impaire. Par exemple, une distorsion Arc peut être utilisée pour générer des images ayant un nombre pair de dimensions en pixels, 76 pixels dans ce cas. |
magick -size 1x1000 gradient: -rotate 90 \
-distort Arc '360 -90 50 0' +repage \
-gravity center -crop 76x76+0+0 +repage gradient_angle_even.png
![[IM Output]](../static/img/canvas/gradient_angle_even.png)
Le '-90' ci-dessus définit l'angle de la « discontinuité » où « zéro » et « maximum » se rejoignent à la même valeur. La valeur '50' devrait représenter plus de la moitié de la taille de l'image finale rognée. Remarquez comment j'ai utilisé un dégradé bien plus long pour générer l'image plus petite. Cela améliore l'exactitude globale du résultat, d'autant plus que l'image s'agrandit. La distorsion Polar étroitement liée peut également générer un tel dégradé, mais comme elle offre un contrôle sur la position exacte du « centre » de la distorsion, vous pouvez garantir qu'elle génère correctement une image de dégradé polaire de taille impaire en pixels. Dans ce cas, une image de 75 pixels (rayon = '36.5'). |
magick -size 1x1000 gradient: -rotate 90 \
+distort Polar '36.5,0,.5,.5' +repage \
-transverse gradient_angle_odd.png
![[IM Output]](../static/img/canvas/gradient_angle_odd.png)
Les deux dernières images peuvent sembler très semblables, à l'exception de leur taille, mais le traitement des pixels les plus centraux diffère légèrement. Si vous regardez de près, vous constaterez que le dernier exemple possède un pixel central gris parfait, alors que l'exemple précédent ne possède pas un unique pixel central, mais quatre. La taille finale de l'image a été déterminée par la valeur '36.5', qui correspond à la moitié des '75' pixels souhaités. Les décalages '.5' constituent l'aspect important pour un traitement correct du centre polaire. Notez que, par défaut, la distorsion place la discontinuité en haut de l'image ; ainsi, la déformation Transverse corrige l'angle et l'emplacement de la discontinuité pour qu'ils correspondent à ceux produits par la distorsion Arc. Voici une variante légèrement différente qui génère un dégradé angulaire mais avec un masque circulaire transparent. |
magick -size 50x1000 gradient: -rotate 90 -alpha set \
-virtual-pixel Transparent +distort Polar 49 +repage \
-transverse gradient_angle_masked.png
![[IM Output]](../static/img/canvas/gradient_angle_masked.png)
La valeur '49' correspond au rayon moins 1, car par défaut une distorsion ajoute un tampon d'anticrénelage de 1 pixel autour de l'image résultante. Ainsi, l'image finale mesure 100x100 pixels.
Les formes et dégradés circulaires peuvent être déformés pour produire d'intéressants dégradés non linéaires. Par exemple, en l'arquant à l'aide d'une distorsion Wave, on peut générer un dégradé de forme approximativement triangulaire. |
magick -size 100x100 radial-gradient: \
-background black -wave -28x200 -crop 100x100+0+0 +repage \
gradient_triangle.jpg
![[IM Output]](../static/img/canvas/gradient_triangle.jpg)
Ou une forme très étrange rappelant un oiseau, générée par une distorsion polaire le long du bord supérieur de la forme circulaire. |
magick -size 100x100 radial-gradient: \
+distort Polar '49' +repage \
gradient_bird.jpg
Dégradés par composition
Vous pouvez également modifier des dégradés en les combinant à l'aide de diverses méthodes de composition. Par exemple, vous pouvez utiliser la méthode de composition Modulus_Add pour produire des dégradés de type store vénitien. |
magick -size 100x100 gradient: \( +clone +clone \) \
-background gray50 -compose ModulusAdd -flatten \
gradient_venetian.jpg
![[IM Output]](../static/img/canvas/gradient_venetian.jpg)
Et vous pouvez même le faire en diagonale. |
magick -size 100x100 gradient: \( gradient: -rotate -90 \) \
\( -clone 0--1 -clone 0--1 \) \
-background gray50 -compose ModulusAdd -flatten \
gradient_vent_diag.jpg
![[IM Output]](../static/img/canvas/gradient_vent_diag.jpg)
Ou, en mélangeant deux dégradés de couleur unie à l'aide des méthodes de composition Channel Copying ou Mathematical Blending, vous pouvez générer de colorés dégradés de carte de couleurs bidimensionnels. |
magick -size 100x100 gradient:yellow-blue \
\( gradient:black-lime -rotate -90 \) \
-compose CopyGreen -composite gradient_colormap.jpg
Dégradés dans d'autres espaces colorimétriques
Bien que le générateur "gradient:" ne puisse actuellement pas générer directement des dégradés dans certains autres espaces colorimétriques (seules des images de dégradé sRGB non linéaires sont créées), vous pouvez transférer des dégradés vers un espace colorimétrique différent pour générer des effets intéressants. Par exemple…
magick -size 30x600 xc:red -colorspace HSB \
gradient: -compose CopyRed -composite \
-colorspace RGB -rotate 90 gradient_rainbow.jpg
Cela convertit d'abord une couleur très saturée ('red') dans l'espace colorimétrique HSL ; n'importe quelle couleur saturée peut être utilisée. Cela règle correctement les canaux de saturation et de luminosité de l'image aux valeurs appropriées. Ensuite, un dégradé est généré et copié dans le canal « teinte » (équivalent au canal « rouge ») de cette image en espace colorimétrique HSL. Et comme par magie, lorsqu'on reconvertit l'image HSL en RGB, on obtient un dégradé arc-en-ciel complet de couleurs totalement saturées. Une autre méthode consiste à générer un dégradé aux valeurs exactes pour l'un de ces espaces colorimétriques, puis à changer l'espace colorimétrique de l'image (à l'aide de "[-set](https://imagemagick.org/command-line-options/#set)"). Cela change l'espace colorimétrique sans modifier les valeurs de couleur que nous avons créées dans l'image. Maintenant, lorsqu'on reconvertit en RGB, on obtient le même arc-en-ciel de valeurs.
magick -size 30x600 gradient:'#FFF-#0FF' -rotate 90 \
-set colorspace HSB -colorspace RGB \
gradient_rainbow_2.jpg
Le résultat est en réalité exactement le même que la méthode précédente, simplement un peu plus direct, dans le sens où nous générons les bonnes valeurs pour l'espace colorimétrique souhaité, puis définissons l'espace colorimétrique auquel ces valeurs appartiennent. Ici, nous reprenons le dégradé angulaire masqué (voir ci-dessus) et le remappons dans l'espace colorimétrique HSB pour générer un cercle de teintes colorées. Le rouge (teinte = 0) est pivoté vers la droite, où il est traditionnellement placé (angle 0 en coordonnées polaires). |
magick -size 100x300 gradient:'#FFF-#0FF' -rotate 90 \
-alpha set -virtual-pixel Transparent +distort Polar 49 +repage \
-rotate 90 -set colorspace HSB -colorspace RGB \
gradient_hue_polar.png
![[IM Output]](../static/img/canvas/gradient_hue_polar.png)
Un exemple semblable au précédent est Color Wheel (roue chromatique), qui est généré en combinant des images de canaux avec à la fois un dégradé de teinte et un dégradé de luminosité.
Dégradé redimensionné
Une astuce présentée par Glenn Randers-Pehrson consiste à créer une image très petite, de deux pixels de large, puis à l'agrandir à la taille d'image nécessaire à l'aide de "[-resize](https://imagemagick.org/command-line-options/#resize)". L'opérateur Resize tente de lisser les images agrandies pour qu'elles paraissent mieux à plus grande échelle. C'est ce lissage que nous exploitons pour générer un dégradé non linéaire. Par exemple, ici nous générons la petite image à l'aide d'une image au format « portable bitmap » (ou format PBM) et la transmettons à IM pour agrandissement. |
echo "P1 1 2 0 1 " | \
magick - -resize 100x100\! gradient_resize.jpg
![[IM Output]](../static/img/canvas/gradient_resize.jpg)
| Certains shells comme 'csh' et ses variantes ne gèrent pas très bien le caractère '!' dans le réglage de géométrie de redimensionnement ci-dessus ── même entre guillemets. C'est pourquoi le caractère barre oblique inverse '\' peut être nécessaire. La prudence est de mise.
---|---
Le dégradé produit n'est pas linéaire : les couleurs indiquées ont un début et une fin adoucis, ce qui les rend bien plus prononcées que ce que vous obtiendriez avec un dégradé normal. La fonction réelle que suit le dégradé dépend (et se rapproche) du filtre de rééchantillonnage exact utilisé par le redimensionnement. Un moyen simple de générer cette image initiale de deux pixels consiste en réalité à utiliser gradient lui-même ! Cela vous permet de spécifier les couleurs directement. Bien sûr, cela vous limitera à un dégradé vertical, à moins que vous ne fassiez également pivoter le résultat. |
magick -size 1x2 gradient:khaki-tomato \
-resize 100x100\! gradient_resize2.jpg
![[IM Output]](../static/img/canvas/gradient_resize2.jpg)
Bien sûr, cette technique ne vous limite pas à une seule dimension. Ici, j'utilise un « portable greymap » de quatre pixels (ou format d'image PGM) pour générer un dégradé bidimensionnel. |
echo "P2 2 2 2 2 1 1 0 " | \
magick - -resize 100x100\! gradient_resize3.jpg
![[IM Output]](../static/img/canvas/gradient_resize3.jpg)
Comme vous pouvez le voir, ce dégradé diagonal n'est pas très linéaire comparé au dégradé pivoté ci-dessus. | Les formats d'image Network Portable Bitmap sont très polyvalents pour générer des images à partir de scripts. C'est un format qui vaut bien la peine d'être connu comme moyen de générer ou de manipuler des données d'image.
---|---
Si vous regardez attentivement, vous constaterez également que le dégradé part du centre du pixel agrandi et ne couvre pas l'image entière d'un bord à l'autre. Cela devient plus clair si nous utilisons un filtre de redimensionnement Triangle. |
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-filter triangle -resize 100x100\! gradient_resize4.jpg
![[IM Output]](../static/img/canvas/gradient_resize4.jpg)
L'opérateur Resize lisse la couleur entre ces pixels selon les réglages du "[filtre de rééchantillonnage](filter.html#filter)". En ajustant le filtre, vous pouvez faire en sorte que le dégradé de redimensionnement produise un effet plus proche du bord à bord. |
magick -size 1x2 gradient: \
-filter Cubic -resize 100x100\! gradient_resize5.jpg
![[IM Output]](../static/img/canvas/gradient_resize5.jpg)
Voici un « dégradé arc-en-ciel » approximatif créé à l'aide de la technique du « redimensionnement ».
magick xc:black xc:red xc:yellow xc:green1 xc:cyan xc:blue xc:black \
+append -filter Cubic -resize 600x30\! gradient_rs_rainbow.jpg
Avec cette méthode, vous pouvez utiliser n'importe quelle combinaison et n'importe quel ordre de couleurs pour la génération des dégradés. Cela la rend particulièrement adaptée à la génération de tables de correspondance de couleurs.
Dégradés par recherche interpolée
Pour plus d'informations sur le réglage "[-interpolate](https://imagemagick.org/command-line-options/#interpolate)", consultez Interpolation Setting. Une autre méthode pour générer des dégradés consiste à utiliser le réglage spécial Interpolation Setting. Ce réglage sert à déterminer la couleur de pixel renvoyée lorsque la recherche de pixel n'est pas un entier et ne correspond donc pas exactement à un pixel précis. L'interpolation détermine alors la couleur d'après les pixels qui entourent le point de recherche. Le réglage par défaut 'bilinear', par exemple, détermine linéairement la couleur pour une recherche qui tombe entre deux pixels.
magick -size 600x30 xc: \( +size xc:gold xc:firebrick +append \) \
-fx 'v.p{i/(w-1),0}' gradient_interpolated.jpg
Ici, la position X de recherche 'i/(w-1)' varie de '0.0' à '1.0' sur la seconde image de deux pixels. Le nombre à virgule flottante produit un dégradé linéaire parfait, à l'instar de ce que fait "[gradient:](#gradient)". Ce qui précède est en réalité presque équivalent (voir Perfect Gradients pour la différence) à l'utilisation de Clut Recolored Images pour recolorer une image de dégradé, à l'aide d'une recherche interpolée dans l'image à deux couleurs.
magick -size 30x600 gradient: -rotate 90 \
\( +size xc:gold xc:firebrick +append \) -clut \
gradient_clut_recolored.jpg
L'utilisation de cette méthode vous permet également de générer des dégradés multicolores.
magick -size 30x600 gradient: -rotate 90 -interpolate Bicubic \
\( +size xc:black xc:tomato xc:wheat +append \) -clut \
gradient_clut.jpg
La limitation, cependant, est que les couleurs ne peuvent être définies qu'avec un espacement égal. Vous ne pouvez pas simplement décaler la position de la couleur intermédiaire, si ce n'est en modifiant grossièrement le dégradé d'entrée en une forme non linéaire afin de décaler ce centre. Pour plus de trois couleurs, la situation empire. Ce qui précède est aussi une bonne technique pour colorer des images en niveaux de gris à l'aide de Duotones, avec la garantie de définir exactement la couleur des demi-tons (contrairement à l'utilisation de l'opérateur Tint).
Les dégradés par recherche interpolée peuvent aussi être étendus à 2 dimensions et générer des dégradés linéaires carrés (Bilinear Interpolation), tout aussi facilement que des dégradés purement unidimensionnels. |
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -fx 'v.p{i/(w-1),j/(h-1)}' \
gradient_bilinear.jpg
![[IM Output]](../static/img/canvas/gradient_bilinear.jpg)
Voici le même exemple mais en utilisant Catrom Interpolation, et généré à l'aide de l'opérateur Distort au lieu de l'opérateur FX très lent. |
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-filter point -interpolate catrom \
-define distort:viewport=100x100 \
-distort Affine '.5,.5 .5,.5 1.5,1.5 99.5,99.5' \
gradient_catrom.jpg
![[IM Output]](../static/img/canvas/gradient_catrom.jpg)
Le point clé pour comprendre ce qui précède est que nous agrandissons la petite image en nous basant sur les centres de ses pixels. Consultez Image Coordinates vs Pixel Coordinates pour les détails. Notez que la plupart des méthodes d'interpolation ont des filtres de redimensionnement interpolés équivalents. Mais l'utilisation de la fenêtre d'affichage et des coordonnées de pixel supprime les effets de bord observés dans les dégradés par redimensionnement précédents, causés par l'agrandissement extrême de l'image très petite.
Le réglage Mesh Interpolation n'est toutefois pas disponible en tant que filtre de redimensionnement. C'est une interpolation bidimensionnelle spéciale qui divise l'aire intra-pixel en deux triangles linéaires plats, articulés le long de la diagonale reliant les coins présentant la différence de couleur minimale. Ainsi, en donnant la même couleur à deux couleurs et en utilisant "-interpolate mesh", vous pouvez générer un dégradé 2D très différent. |
magick \( xc:red xc:gold +append \) \
\( xc:gold xc:green +append \) -append \
-filter point -interpolate mesh \
-define distort:viewport=100x100 \
-distort Affine '.5,.5 .5,.5 1.5,1.5 99.5,99.5' \
gradient_mesh.jpg
![[IM Output]](../static/img/canvas/gradient_mesh.jpg)
Comme les deux coins jaunes diagonalement opposés sont identiques, une diagonale jaune a été utilisée pour les relier. Les autres couleurs étant mappées linéairement sur ces triangles. Si les deux couleurs diagonales ne sont pas identiques, vous pourrez obtenir une division diagonale différente.
Créez votre propre dégradé
L'opérateur FX DIY vous permet de définir vos propres dégradés ou d'autres générations d'image, à partir de la position du pixel courant. Comme cet opérateur a besoin d'une image sur laquelle travailler, vous pouvez générer vos dégradés ou autres images pour qu'ils correspondent à cette image. Autrement dit, vous n'avez pas besoin de connaître la taille de l'image pour générer un dégradé destiné à celle-ci ! Par exemple, vous pouvez facilement générer un dégradé linéaire, correctement dimensionné pour l'image sur laquelle vous travaillez. |
magick rose: -channel G -fx 'i/w' -separate gradient_fx_linear.gif
![[IM Output]](../static/img/canvas/gradient_fx_linear.gif)
| Lorsque vous générez des dégradés en niveaux de gris, vous pouvez rendre l'opérateur -fx 3 fois plus rapide, simplement en lui demandant de ne générer qu'un seul canal de couleur, comme le canal 'G' (vert) dans l'exemple ci-dessus. Ce canal peut ensuite être Séparé pour former l'image en niveaux de gris requise. Cela peut représenter un très grand gain de vitesse, en particulier lorsqu'on utilise une formule "[-fx](https://imagemagick.org/command-line-options/#fx)" très complexe.
---|---
Vous pouvez même générer quelques dégradés non linéaires astucieux. |
magick rose: -channel G -fx '(i/w)^4' -separate gradient_fx_x4.gif
magick rose: -channel G -fx 'cos(pi*(i/w-.5))' \
-separate gradient_fx_cos.gif
![[IM Output]](../static/img/canvas/gradient_fx_cos.gif)
Que diriez-vous d'un dégradé radial linéaire circulaire en 2 dimensions (un cône). |
magick -size 100x100 xc: -channel G \
-fx 'rr=hypot(i/w-.5, j/h-.5); 1-rr*1.42' \
-separate gradient_fx_radial.gif
![[IM Output]](../static/img/canvas/gradient_fx_radial.gif)
| La fonction "[-fx](https://imagemagick.org/command-line-options/#fx)" 'rr=hypot(xx,yy)' a été ajoutée dans IM v6.3.6 pour accélérer l'expression très couramment utilisée 'rr=sqrt(xx*xx+yy*yy)'. Cela signifie aussi que nous n'avons plus besoin de faire des affectations supplémentaires telles que 'xx=i/w-.5' lors de la création d'un dégradé radial.
---|---
La valeur '1.42' (ou sqrt(2)) ci-dessus contrôle la taille globale du dégradé par rapport aux dimensions de l'image. Ainsi, le rayon du dégradé (la distance du noir par rapport au centre) correspond à la distance diagonale jusqu'au coin. Vous pouvez même retirer le 'sqrt()' (intégré à la fonction 'hypot()') de l'expression pour obtenir un dégradé sphérique plus intéressant, qui peut être utile pour les Effets d'ombrage 3D. |
magick -size 100x100 xc: -channel G \
-fx 'xx=i/w-.5; yy=j/h-.5; rr=xx*xx+yy*yy; 1-rr*4' \
-separate gradient_fx_spherical.gif
![[IM Output]](../static/img/canvas/gradient_fx_spherical.gif)
Remarquez comment j'utilise quelques expressions d'affectation pour simplifier le calcul de la distance par rapport au centre de l'image, avant de la transformer en dégradé. Cette fonctionnalité a été ajoutée dans IM v6.3.0. En utilisant une fonction de puissance élevée, vous pouvez donner aux photos un effet de fondu autour des bords rectangulaires de l'image. Ajustez la valeur de puissance '4' pour contrôler l'importance du fondu. |
magick -size 100x100 xc: -channel G \
-fx '(1-(2*i/w-1)^4)*(1-(2*j/h-1)^4)' \
-separate gradient_fx_quad2.gif
![[IM Output]](../static/img/canvas/gradient_fx_quad2.gif)
Voici un dégradé angulaire, généré à l'aide de mathématiques directes. |
magick -size 100x100 xc: -channel G \
-fx '.5 - atan2(j-h/2,w/2-i)/pi/2' \
-separate gradient_fx_angular.gif
![[IM Output]](../static/img/canvas/gradient_fx_angular.gif)
Notez que la fonction 'atan2(y,x)' renvoie un angle en radians compris entre -PI et +PI (voir sa page de manuel), de sorte que sa sortie doit être mise à l'échelle et translatée pour tenir correctement dans une plage de couleurs de 0.0 à 1.0. C'est pourquoi ce qui précède paraît beaucoup plus complexe qu'il ne l'est réellement.Ce dernier exemple peut être généré plus rapidement en Déformant un dégradé.
Dégradés DIY plus complexes
À NOTER : cette section a été créée avant l'ajout des Points de couleur épars, et elle a eu une influence directe sur leur création. Bien entendu, une fonction FX peut générer des dégradés de couleur. Par exemple, voici un dégradé basé sur des rapports de distance, utilisant une expression FX extrêmement complexe. |
magick -size 100x100 xc: +size xc:red xc:yellow -colorspace RGB \
-fx 'ar=hypot( i/w-.8, j/h-.3 )*4;
br=hypot( i/w-.3, j/h-.7 )*4;
u[1]*br/(ar+br) + u[2]*ar/(ar+br)' \
-colorspace RGB gradient_dist_ratio.gif
![[IM Output]](../static/img/canvas/gradient_dist_ratio.gif)
| Le traitement de l'image a été effectué dans un espace colorimétrique linéaire (RGB) afin d'éviter l'« assombrissement sRGB » lors du mélange de couleurs primaires aussi intenses. Voir Traitement d'images réelles pour plus de détails.
---|---
Lorsqu'on passe de deux points à trois points, le rapport de la quantité de couleur que fournit chaque « point de contrôle » devient un peu plus complexe et utilise une technique appelée interpolation par pondération inverse de la distance (IDW). Vous pouvez voir davantage de détails mathématiques à ce sujet dans Wikipedia, IDW. Voici un exemple de distance inverse pour trois points. |
magick -size 100x100 xc: +size xc:red xc:yellow xc:lime -colorspace RGB \
-fx 'ar=1/max(1, hypot(i-50,j-10) );
br=1/max(1, hypot(i-10,j-70) );
cr=1/max(1, hypot(i-90,j-90) );
( u[1]*ar + u[2]*br + u[3]*cr )/( ar+br+cr )' \
-colorspace sRGB gradient_inverse.gif
![[IM Output]](../static/img/canvas/gradient_inverse.gif)
Et voici un exemple utilisant l'inverse du carré de la distance, qui est la méthode plus habituelle pour une interpolation IDW. Elle est aussi connue sous le nom de méthode d'interpolation de Shepard. |
magick -size 100x100 xc: +size xc:red xc:yellow xc:lime -colorspace RGB \
-fx 'ar=1/max(1, (i-50)*(i-50)+(j-10)*(j-10) );
br=1/max(1, (i-10)*(i-10)+(j-70)*(j-70) );
cr=1/max(1, (i-90)*(i-90)+(j-90)*(j-90) );
( u[1]*ar + u[2]*br + u[3]*cr )/( ar+br+cr )' \
-colorspace sRGB gradient_shepards.gif
![[IM Output]](../static/img/canvas/gradient_shepards.gif)
Notez que la fonction 'hypot()' n'a pas été utilisée ci-dessus, car il n'est pas nécessaire de calculer la racine carrée de la distance. Ce qui précède a désormais été implémenté à l'aide des méthodes Sparse Color '[Inverse](#inverse)' et '[Shepard's](#shepards)'. Ainsi, ce qui précède peut maintenant se faire bien plus simplement en utilisant…
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '50,10 red 10,70 yellow 90,90 lime' \
-colorspace sRGB gradient_inverse_alt.gif
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Shepards '50,10 red 10,70 yellow 90,90 lime' \
-colorspace sRGB gradient_shepards_alt.gif
Le problème lié à l'utilisation de la « distance inverse » ou de la « méthode de Shepard » (distance au carré inverse) est que tous les « points de contrôle » ont un effet global sur l'ensemble de l'image. Il en résulte une sorte de « couleur moyenne » sous-jacente entre les points, et surtout à grande distance de tous les points de contrôle. Cela produit à son tour des « taches » de couleur plutôt qu'un dégradé de couleur lisse.
Dégradés DIY et teintes
-- (les teintes sont difficiles à manipuler)
À NOTER : il s'agissait d'une sorte de tentative ratée de générer un effet arc-en-ciel intéressant. Ce fut un échec, mais j'en ai beaucoup appris, ce que je vous présente ici. Ce qui précède fonctionne bien, mais je voulais essayer de faire mieux. Je pensais que je pourrais peut-être générer un dégradé arc-en-ciel de couleurs vives entre les points, au lieu de générer des taches qui se fondent en une couleur moyenne. Pour générer un dégradé de teintes, j'ai donc essayé de réaliser l'interpolation par pondération inverse de la distance dans l'espace colorimétrique HSB, tout en remplaçant le jaune par le bleu afin de répartir les couleurs plus équitablement autour de la teinte, et en espérant fournir une autre façon de générer une roue chromatique (voir Dégradés dans d'autres espaces colorimétriques ci-dessus). |
magick -size 100x100 xc: +size xc:red xc:blue xc:lime -colorspace HSB \
-fx 'ar=1/max(1, (i-50)*(i-50)+(j-10)*(j-10) );
br=1/max(1, (i-10)*(i-10)+(j-70)*(j-70) );
cr=1/max(1, (i-90)*(i-90)+(j-90)*(j-90) );
( u[1]*ar + u[2]*br + u[3]*cr )/( ar+br+cr )' \
-colorspace sRGB gradient_shepards_HSB.gif
![[IM Output]](../static/img/canvas/gradient_shepards_HSB.gif)
Comme vous pouvez le voir, toutes les couleurs étaient bien vives, puisque nous ne générons qu'un dégradé de teintes. Cependant, le résultat paraît aussi très étrange, ce qui est causé par la nature « cyclique » du canal de couleur « teinte ». Par conséquent, la zone entre le bleu et le rouge fait le long tour en passant par une teinte verte, plutôt que d'emprunter le chemin « modulo » plus court via une teinte violette. Après de nombreuses recherches, j'ai finalement découvert comment effectuer les mathématiques du modulo nécessaires pour réaliser correctement ce qui précède, en utilisant une Moyenne circulaire pour la moyenne pondérée des distances. Cela implique de convertir la teinte, en tant qu'angle polaire, en coordonnées rectangulaires X et Y. Cela permet d'effectuer des mathématiques linéaires, nous laissant réaliser une pondération linéaire des valeurs, de manière appropriée. Le résultat est ensuite reconverti en une teinte angulaire. |
magick -size 100x100 xc: +size xc:red xc:blue xc:lime \
-colorspace HSB -channel R \
-fx 'aa=u[1]*2*pi; ba=u[2]*2*pi; ca=u[3]*2*pi;
ar=1/max(1, hypot(i-50,j-10) );
br=1/max(1, hypot(i-10,j-70) );
cr=1/max(1, hypot(i-90,j-90) );
nr=ar+br+cr;
mod(atan2( ( sin(aa)*ar + sin(ba)*br + sin(ca)*cr )/nr,
( cos(aa)*ar + cos(ba)*br + cos(ca)*cr )/nr
)/(2*pi)+1, 1)' \
-separate -background white -combine +channel \
-set colorspace HSB -colorspace sRGB gradient_circular_mean_hue.gif
![[IM Output]](../static/img/canvas/gradient_circular_mean_hue.gif)
REMARQUE : ce qui précède n'a effectué ses opérations que sur le canal de teinte. Pour une image réelle, il faudrait encore opérer (comme d'habitude) sur les canaux de saturation et de brillance. Comme vous pouvez le voir, nous obtenons maintenant un dégradé correct entre le rouge et le bleu, bien que la méthode, appliquée uniquement à des couleurs primaires présentant une forte séparation angulaire, ait tendance à générer des changements de dégradé très brusques au milieu. Autrement dit, bien que le résultat soit correct, la variation angulaire de la teinte n'est pas linéaire pour de très grandes variations d'effets de teinte. Elle fonctionnerait bien pour moyenner de nombreuses teintes proches, mais pas pour ces primaires très espacées. Je suis même passé à une « pondération inverse » plus forte plutôt qu'à la méthode plus habituelle du « carré inverse » ou de « Shepard » (voir ci-dessus) et, bien que cela ait amélioré les choses, les changements de teinte se comprimaient toujours au centre en raison des effets non linéaires. Comme les couleurs d'entrée sont constantes, les préconvertir en coordonnées teinte-x et teinte-y, appliquer la pondération de Shepard sur ces canaux, puis reconvertir, rendrait en fait le processus encore plus rapide. Autrement dit, convertir les couleurs d'un espace colorimétrique HSB vers un espace colorimétrique Hx,Hy,S,B, pour appliquer la technique. Si cela est fait, alors le point central et même le dégradé régulier entre les points s'ombreraient vers le blanc (le point central d'un espace colorimétrique HSB). Si cela était réalisé dans l'espace colorimétrique HSL, cette zone s'ombrerait vers un gris de tonalité moyenne.
Cette conversion d'une teinte polaire en coordonnées X-Y serait, à certains égards, semblable au simple fait d'effectuer les calculs dans un espace RGB non polaire, qui présente ces mêmes effets d'ombrage vers le gris (voir les exemples précédents). Donc, si en utilisant une Moyenne circulaire nous ne faisons en réalité que convertir un espace colorimétrique HSB en une variante RGB fortement déformée, pourquoi ne pas simplement réaliser la tâche dans un espace colorimétrique RGB linéaire et saturer les couleurs, pour générer la teinte !
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '50,10 red 10,70 blue 90,90 lime' \
-colorspace sRGB gradient_inverse_RGB.png
magick gradient_inverse_RGB.png -colorspace HSB \
-channel GB -evaluate set 100% +channel \
-colorspace sRGB gradient_inverse_RGB_Hue.gif
| Le traitement de l'image a été effectué dans un espace colorimétrique linéaire (RGB) afin d'éviter l'« assombrissement sRGB » lors du mélange de couleurs primaires aussi intenses. Voir Traitement d'images réelles pour plus de détails.
---|---
Comme vous pouvez le voir, nous obtenons pratiquement exactement le même résultat qu'auparavant, mais en ayant supprimé toutes les « mathématiques du modulo » complexes. Cependant, je ne suis toujours pas plus près d'obtenir une répartition plus linéaire des teintes entre les points de couleur de départ. La morale de tout cela est que travailler avec les teintes est difficile, non seulement à cause de la « discontinuité du rouge », mais aussi en raison des effets non linéaires qui se produisent lorsque les couleurs sont très espacées. Et au bout du compte, le résultat était le même que si j'avais réalisé la tâche directement dans l'espace RGB linéaire en saturant les couleurs. Essentiellement, bien que les espaces colorimétriques HSB et HSL soient amusants, ce ne sont pas des espaces colorimétriques linéaires, réalistes ou pratiques pour travailler. C'est probablement aussi pour cela que très peu d'opérations fonctionnent réellement directement avec la teinte.
Générer le dégradé parfait (mathématiquement)
Générer un dégradé mathématique parfait, comme pour les Transformées de Fourier (qui sont cycliques), le Mappage d'images, ou même les Mathématiques de dégradé, nécessite des dégradés particuliers, différents des dégradés que nous avons examinés jusqu'ici. Qu'est-ce que j'entends par là ? Eh bien, voici une petite image "gradient:" de 1x5 pixels, que j'ai Mise à l'échelle pour que vous puissiez voir les couleurs de chaque pixel. |
magick -size 1x5 gradient: -scale 2000% gradient.png
![[IM Output]](../static/img/canvas/gradient.png)
Cette image crée un dégradé qui va d'une couleur « blanche » exacte le long de la toute première ligne, à une couleur « noire » exacte le long de la toute dernière ligne. C'est un dégradé « idéalisé », et généralement exactement ce qu'un utilisateur souhaite, car il contient réellement les couleurs que l'utilisateur a spécifiées. Cependant, bien que ce soit ce qu'un utilisateur attend, ce n'est pas un dégradé mathématiquement correct. Comme nous l'avons vu dans Coordonnées d'image vs coordonnées de pixel, les pixels ont en réalité une surface, et de ce fait le pixel blanc en haut de l'image représente le centre de ce pixel, tandis que le noir représente le centre du pixel tout en bas. C'est-à-dire non pas le bord de l'image, mais à 1/2 pixel du bord. Mathématiquement, les images commencent au bord. Ainsi, pour générer un dégradé mathématiquement parfait, vous devez spécifier les emplacements des couleurs au bord de l'image, en coordonnées de pixel. Par conséquent, en coordonnées d'image, les positions sont décalées de 1/2 pixel, et la taille de l'image correspond exactement au nombre de pixels de l'image (une distance), plutôt qu'à un emplacement inférieur de 1 pixel à la taille de l'image. Une façon de générer un dégradé mathématiquement parfait est d'utiliser Barycentric Sparse Color (examiné en détail dans la section suivante) pour générer un dégradé parfait de bord à bord… |
magick -size 1x5 xc: \
-sparse-color Barycentric '0,-0.5 white 0,%[fx:h-.5] black' \
-scale 2000% gradient_math.png
![[IM Output]](../static/img/canvas/gradient_math.png)
Notez que les coordonnées utilisées vont de -0.5 à la hauteur de l'image moins 0.5, soit les coordonnées de pixel des bords réels de l'image. Et si vous regardiez de près les résultats, vous constateriez que les pixels tout en haut et tout en bas ne sont ni blancs ni noirs. Le pixel a la couleur du dégradé au centre du pixel. Parce que ce dégradé est mathématiquement correct, il se « juxtaposera » correctement lorsqu'il sera utilisé dans des situations spéciales de « juxtaposition » ou « cycliques ». L'image de dégradé précédente ne se « juxtaposera » pas correctement. Vous obtenez un pixel blanc pur, juste à côté du pixel noir pur, ce qui crée un écart d'un pixel ou une « disjonction » dans le cycle mathématique, dans les situations où le blanc pur et le noir pur sont généralement considérés comme des valeurs équivalentes. Une façon plus simple consiste à générer une image "[gradient:](#gradient)" plus longue d'un pixel, puis à supprimer un pixel à l'une des extrémités (selon le réglage "[-gravity](https://imagemagick.org/command-line-options/#gravity)" en cours). Par exemple, ici j'ai supprimé le pixel blanc du haut, car avoir un pixel noir (ou une valeur nulle) est souvent plus souhaitable dans le résultat final. |
magick -size 1x6 gradient: -chop 0x1 -scale 2000% gradient_chopped.png
![[IM Output]](../static/img/canvas/gradient_chopped.png)
L'image de dégradé résultante peut ensuite être Pivotée selon les besoins, afin de générer l'image requise pour un traitement d'image ultérieur. Cependant, bien que ce dégradé « cycle » correctement, la position réelle de la couleur n'est pas tout à fait exacte. Mais dans de nombreux cas, cela suffit. Si vous avez besoin d'un « dégradé parfait », je vous recommande d'utiliser un dégradé sparse color. En résumé… Un peu de réflexion sur ce que vous attendez exactement de votre dégradé peut faire une grande différence dans la précision de vos résultats finaux. Mais si cela n'a pas d'importance, alors ne vous en souciez pas, utilisez ce qui est le plus simple pour la tâche à accomplir.
Points de couleur épars
L'opérateur "[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color) ", ajouté dans IM v6.4.3-0, prend une image et définit la couleur donnée à chacune des coordonnées 'x,y' en virgule flottante fournies. C'est-à-dire, sous la forme…
-sparse-color {method} 'x,y color x,y color x,y color ...'
Les pixels restants (limités selon le réglage "[-channel](https://imagemagick.org/command-line-options/#channel)") seront ensuite mappés selon leur relation à ces points de couleur isolés, de façon à lisser les couleurs entre ces points. La method définit ce que sera cette relation. Naturellement, il existe de nombreuses façons de définir ce que devrait être la couleur intermédiaire, et la méthode que vous choisissez dépend vraiment de ce que vous cherchez à obtenir. Cela peut aussi être classé comme une version entièrement libre de l'interpolation bidimensionnelle (voir Interpolation, Wikipedia). L'agrandissement d'image, ou Redimensionnement, en est en réalité un sous-ensemble spécialisé, mais où l'on part d'une grille fixe complète de pixels à agrandir. Malheureusement, peu des Filtres de redimensionnement ou des Méthodes d'interpolation, spécialement conçus pour traiter une grille de points, se traduiront directement en un ensemble libre de points de couleur épars et séparés. Autrement dit, un redimensionnement impliquant une grille incomplète ne fonctionne tout simplement pas. Cela est également lié aux méthodes des « systèmes d'information géographique (SIG) », où les paysages sont mesurés à l'aide de points d'altitude épars et séparés (qui sont rarement disposés en une grille stricte), le reste du paysage étant déterminé à partir de ces points isolés. Dans une situation similaire, la météorologie dispose souvent de points isolés de pression atmosphérique et de température, qu'il faut ensuite interpoler. Généralement, après l'interpolation, les cartes sont encore traitées pour générer des « iso-lignes » indiquant les points de valeur égale (altitude, pression, température), produisant les diverses cartes météorologiques que presque tout le monde connaît. Dans ce cas, on penserait à l'image générée comme à une simple « carte d'altitude » en niveaux de gris des données d'entrée, ou peut-être même des trois variables simultanément, chacune sur un « canal » d'image distinct.
Barycentric (dégradé triangulaire)
La méthode "Barycentric" mappe trois points, et seulement trois, en un triangle linéaire de couleur. Les couleurs à l'extérieur de ce triangle se prolongent comme précédemment. J'ai marqué les points d'entrée d'un petit cercle, de sorte que les couleurs que vous voyez sont toutes les valeurs interpolées générées par l'Opérateur Sparse Color. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Barycentric '30,10 red 10,80 blue 90,90 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82 circle 90,90 90,92' \
sparse_barycentric.png
![[IM Output]](../static/img/canvas/sparse_barycentric.png)
| Le traitement de l'image a été effectué dans un espace colorimétrique linéaire (RGB) afin d'éviter l'« assombrissement sRGB » lors du mélange de couleurs primaires aussi intenses. Voir Traitement d'images réelles pour plus de détails.
---|---
Si quatre points ou plus sont donnés, un « meilleur ajustement » sera effectué sur l'ensemble des points fournis, et de ce fait les points réels risquent de ne pas obtenir la couleur exacte spécifiée pour ces points. Attention toutefois : le dégradé ne fait pas que « s'arrêter », il continue de changer au-delà de ces points. Traditionnellement, un dégradé barycentrique sera limité à l'intérieur du triangle enveloppant les points utilisés pour le générer. Par exemple… |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Barycentric '30,10 red 10,80 blue 90,90 lime' \
-colorspace sRGB -fill white -stroke black \
\( -size 100x100 xc:black -draw 'polygon 30,10 10,80 90,90' \) \
-alpha off -compose CopyOpacity -composite \
-draw 'circle 30,10 30,12 circle 10,80 10,82 circle 90,90 90,92' \
sparse_bary_triangle.png
magick -size 100x100 xc:none -draw "polygon 30,10 10,80 90,90" \
-colorspace RGB -channel rgb \
-sparse-color Barycentric '30,10 red 10,80 blue 90,90 lime' \
-colorspace sRGB sparse_bary_triangle_2.png
![[IM Output]](../static/img/canvas/sparse_bary_triangle_2.png)
| Les masques triangulaires utilisés ci-dessus sont trop grands de 1/2 pixel en raison de la manière dont draw dessine une ligne supplémentaire autour de ses formes. Voir Draw Fill Bounds pour plus de détails. Cela pourrait poser problème lors de la génération d'un maillage triangulaire de dégradés.
---|---
La méthode 'barycentric' consiste en réalité à mapper une équation affine linéaire à chacun des trois canaux de couleur séparément. Ainsi, si je sépare chacun des canaux de couleur de l'exemple à trois points ci-dessus, vous obtenez trois dégradés linéaires simples dans chaque canal de couleur.
magick sparse_barycentric.png -separate sparse_bary_%d.gif
C'est uniquement du fait de l'utilisation de couleurs primaires que les dégradés ci-dessus ont tous été mappés parallèlement à l'un des côtés du triangle. Ce n'est pas le cas en général. Mais vous obtiendrez toujours un simple dégradé linéaire dans chaque canal distinct de l'image, et un plan plat de valeurs dans l'espace colorimétrique 3D.
Barycentric et dégradés à deux couleurs
Cet effet de parallélisme du dégradé barycentrique triangulaire est en réalité très utile. Si deux des points étaient réglés sur la même couleur, alors ces deux points définiraient l'« angle » du dégradé entre eux et l'autre point coloré. Par exemple, en réglant deux des points sur 'red', le dégradé sera rendu parallèle aux deux points 'red'… |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Barycentric '30,10 red 10,80 red 90,90 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82 circle 90,90 90,92' \
sparse_bary_gradient.png
![[IM Output]](../static/img/canvas/sparse_bary_gradient.png)
Voici le même exemple, mais avec l'un des points de contrôle d'angle déplacé pour montrer comment il règle l'angle du dégradé. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Barycentric '50,70 red 10,80 red 90,90 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 50,70 50,72 circle 10,80 10,82 circle 90,90 90,92' \
sparse_bary_gradient_2.png
Dégradés diagonaux
Cela offre un moyen simple de générer n'importe quel dégradé diagonal linéaire en n'utilisant que deux couleurs. Par exemple, voici une manière particulièrement élégante de créer un dégradé diagonal, allant d'un coin à un autre coin, pour une image d'entrée de N'IMPORTE QUELLE taille.
magick -size 600x60 xc: -colorspace RGB \
-sparse-color barycentric '0,0 skyblue -%w,%h skyblue %w,%h black' \
-colorspace sRGB diagonal_gradient.jpg
Et pour s'aligner sur les deux autres coins…
magick -size 600x60 xc: -colorspace RGB \
-sparse-color barycentric '0,%h black -%w,0 black %w,0 skyblue' \
-colorspace sRGB diagonal_gradient_2.jpg
Ces « dégradés diagonaux » produisent un dégradé d'aspect naturel même avec des images longues comme celle ci-dessus. Étudiez les emplacements des trois points de couleur, en particulier les deux points de couleur identique qui définissent l'angle du dégradé entre les deux coins. Remarquez que, dans les deux cas, l'un de ces points n'est même pas situé à l'intérieur de l'image elle-même ! Notez également l'utilisation des Échappements par pourcentage pour que les positions s'ajustent automatiquement à la taille des images sur lesquelles le dégradé est dessiné.
Dégradés à deux points
Si seuls deux points de couleur sont donnés, IM générera le troisième point à votre place, de sorte que l'angle soit perpendiculaire entre les deux points d'origine. Le résultat est un simple dégradé linéaire sur lequel vous disposez d'un grand contrôle. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Barycentric '30,10 red 90,90 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 90,90 90,92' \
sparse_bary_two_point.png
![[IM Output]](../static/img/canvas/sparse_bary_two_point.png)
Les dégradés à deux points ne fonctionnent cependant pas très bien lorsqu'ils sont appliqués aux coins d'images très « larges » ou « hautes » (à rapport d'aspect élevé). En gros, le dégradé n'est pas aligné en diagonale, contrairement aux dégradés à trois points ci-dessus. Il est incliné, mais pas suffisamment pour être « intéressant ».
magick -size 600x60 xc: -colorspace RGB \
-sparse-color barycentric '0,0 skyblue %w,%h black' \
-colorspace sRGB sparse_bary_two_point_wide.jpg
Bilinear (dégradé à 4 points)
Cette méthode ajuste une équation à 4 points, sur les trois canaux de couleur, pour produire un dégradé de couleur uniforme entre les points, et au-delà. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Bilinear '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_bilinear.png
![[IM Output]](../static/img/canvas/sparse_bilinear.png)
Vous pouvez constater cet « ajustement à 4 points » en prenant l'image ci-dessus et en séparant les dégradés de chaque canal de couleur.
magick sparse_bilinear.png -separate sparse_bilin_%d.gif
Remarquez comment l'équation produit des courbes (des courbes quadratiques, en réalité). Cependant, si les 4 points forment des lignes parallèles, le dégradé généré deviendra linéaire. Cette méthode est en fait équivalente à la méthode d'Interpolation bilinéaire (voir Dégradés par recherche interpolée ci-dessous), lorsque les 4 points sont alignés sur une grille orthogonale (rectangulaire). Si moins de 4 points sont donnés, la fonction ci-dessus sera remplacée par une méthode '[Barycentric](#barycentric)' à 3 points (voir ci-dessus). Si plus de quatre points sont donnés, elle effectuera un meilleur ajustement de tous les points, et ne correspondra donc peut-être pas réellement à la couleur donnée au point spécifié. Cela n'est pas recommandé.
Voronoi (couleur la plus proche)
La méthode "Voronoi" mappe simplement chaque pixel au point de couleur le plus proche que vous avez fourni. Cela divise essentiellement l'image en un ensemble de « cellules » polygonales autour de chaque point. Par exemple… |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Voronoi '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_voronoi.gif
![[IM Output]](../static/img/canvas/sparse_voronoi.gif)
Comme vous pouvez le voir, aucune tentative n'est faite pour anticréner les « cellules » colorées autour de chaque point. Le bord de chaque cellule tombe en réalité exactement à mi-chemin entre les plus proches voisins de chaque point. Cela peut être utilisé, par exemple, pour générer des masques permettant de découper l'image de diverses manières. Attribuez simplement le blanc à un point et le noir à tous les autres pour extraire une seule « cellule » de l'image. Si vous voulez lisser (anticréner) le résultat, vous pouvez utiliser une forme de Suréchantillonnage pour lisser l'image. Par exemple, en générer une 4 fois plus grande, puis la ramener à la taille voulue avec "[-scale](https://imagemagick.org/command-line-options/#scale)". |
magick -size 400x400 xc: -colorspace RGB \
-sparse-color Voronoi '120,40 red 40,320 blue 270,240 lime 320,80 yellow'
\
-scale 25% -colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_voronoi_ssampled.png
![[IM Output]](../static/img/canvas/sparse_voronoi_ssampled.png)
| Tout le traitement des images a été effectué dans un espace colorimétrique linéaire (RGB) afin d'éviter l'« assombrissement sRGB » lors du mélange de couleurs primaires aussi intenses. Voir Traitement d'images réelles pour plus de détails.
---|---
La façon la plus simple (bien que peu esthétique) consiste simplement à flouter très légèrement l'image… |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Voronoi '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-blur 1x0.7 -colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_voronoi_smoothed.png
![[IM Output]](../static/img/canvas/sparse_voronoi_smoothed.png)
En floutant l'image générée de façon importante, vous pouvez mettre en place des dégradés non linéaires entre les « cellules » qui ont été générées. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Voronoi '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-blur 0x15 -colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_voronoi_blur.png
![[IM Output]](../static/img/canvas/sparse_voronoi_blur.png)
Plus le "[-blur](https://imagemagick.org/command-line-options/#blur)" est grand, plus le dégradé entre les diverses « cellules » est important. Attention toutefois : cela peut ne pas préserver les petites cellules colorées, ni garantir que le point d'origine conserve la couleur qui lui a été donnée, s'il est proche du bord (et d'un autre point) d'une couleur différente. En utilisant une technique spéciale de « flou linéaire », mise au point par Fred Weinhaus, vous pouvez produire un dégradé linéaire de largeur fixe entre les cellules. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Voronoi '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-blur 10x65535 -colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_voronoi_gradient.png
![[IM Output]](../static/img/canvas/sparse_voronoi_gradient.png)
La sortie non floutée pourrait aussi être transmise à diverses techniques de Détection de contours pour générer différents bords délimités. Vous pouvez remapper l'image via un Convertisseur matriciel vers vectoriel pour générer des lignes vectorielles. J'ai toutefois constaté que les réglages 'autotrace' par défaut peuvent devoir être ajustés avec "-corner-threshold 120" pour qu'il détecte mieux les coins.
Shepards (taches de couleur)
La méthode "Shepards" utilise un rapport des carrés inverses des distances à chacun des points donnés pour déterminer la couleur du canevas en chaque point. Voir Dégradés DIY plus complexes ci-dessus pour des exemples de la manière dont les mathématiques sont réalisées. C'est un peu comme si l'on disposait de projecteurs de couleur en chaque point, interagissant les uns avec les autres à mesure que la lumière se propage, pour tendre à l'infini vers une moyenne uniforme de toutes les couleurs données. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards.png
![[IM Output]](../static/img/canvas/sparse_shepards.png)
| Le traitement de l'image a été effectué dans un espace colorimétrique linéaire (RGB) afin d'éviter l'« assombrissement sRGB » lors du mélange de couleurs primaires aussi intenses. Voir Processing Real Images pour plus de détails.
---|---
En entourant une zone précise d'une couleur similaire, il est possible de générer un plateau de cette couleur précise ; toutefois les frontières entre les points d'encadrement peuvent « fuir », et le centre du « plateau » peut s'affaisser pour former une cuvette peu profonde (selon la distance aux autres points de couleur). Cette méthode est aussi celle utilisée pour générer un champ de déplacement, comme celui employé dans Shepards Image Distortions. Dans ce cas, ce sont les vecteurs de déplacement X et Y qui sont mappés plutôt que les valeurs de couleur R,G,B.
Inverse (points de couleur nets)
La méthode « Inverse » est pratiquement identique à « Shepards », si ce n'est qu'elle utilise une pondération par distance inverse plus directe des points donnés. Voir More Complex DIY Gradients ci-dessus pour des exemples de la façon dont les calculs sont effectués. Ce fut un ajout bien plus tardif à la version 6.6.9-7 d'ImageMagick. Par exemple… |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_inverse.png
![[IM Output]](../static/img/canvas/sparse_inverse.png)
Comme vous pouvez le voir, elle génère des points de couleur nets, qui se fondent rapidement dans la « couleur moyenne » de l'arrière-plan. Par comparaison avec la méthode Shepards, qui génère des taches arrondies avec une couleur « plate » autour des points de couleur. Elle fonctionne toutefois mieux pour générer des dégradés linéaires où tous les points de contrôle forment une ligne. C'est-à-dire pour générer des dégradés unidimensionnels le long d'une ligne précise de l'image. Il reste cependant un point à préciser. La vitesse à laquelle ces points de couleur chutent vers un niveau proche de la « moyenne » est contrôlée par leur proximité. Placez deux sources ponctuelles proches l'une de l'autre et elles chutent rapidement ; plus elles sont éloignées, plus l'influence de chaque couleur est importante.
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '45,45 red 55,55 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 45,45 45,47 circle 55,55 55,57' \
sparse_inverse_near.png
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '30,30 red 70,70 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,30 30,32 circle 70,70 70,72' \
sparse_inverse_far.png
De même, si vous « doublez » un point précis (exactement dessus, ou tout près l'un de l'autre) avec la même couleur ou une couleur similaire, vous rendrez ce point de couleur deux fois plus fort. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '30,30 red 75,65 lime 65,75 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,30 30,32 circle 75,65 75,67 circle 65,75 65,77 '
\
sparse_inverse_stronger.png
![[IM Output]](../static/img/canvas/sparse_inverse_stronger.png)
Ces effets s'appliquent également à la méthode '[Shepards](#shepards)' !
Facteur de puissance de Shepards
Les méthodes de sparse color Shepards et Inverse sont en réalité identiques, mais avec des « niveaux de puissance » différents appliqués aux pondérations par distance inverse (respectivement 2.0 et 1.0). Depuis IM v6.8.0-10, vous pouvez régler ce niveau de puissance à l'aide d'un define opérationnel, 'shepards:power', qui sera utilisé par la méthode '[Shepards](#shepards)'. Par exemple
magick -size 100x100 xc: -colorspace RGB -define shepards:power=0.5 \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_pow0.5.png
magick -size 100x100 xc: -colorspace RGB -define shepards:power=1 \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_pow1.png
magick -size 100x100 xc: -colorspace RGB -define shepards:power=2 \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_pow2.png
magick -size 100x100 xc: -colorspace RGB -define shepards:power=3 \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_pow3.png
magick -size 100x100 xc: -colorspace RGB -define shepards:power=8 \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_pow8.png
![[IM Output]](../static/img/canvas/sparse_shepards_pow0.5.png)
puissance 0.5 | ![[IM Output]](../static/img/canvas/sparse_shepards_pow1.png)
puissance 1.0
(inverse) | ![[IM Output]](../static/img/canvas/sparse_shepards_pow2.png)
puissance 2.0
(shepards) | ![[IM Output]](../static/img/canvas/sparse_shepards_pow3.png)
puissance 3.0 | ![[IM Output]](../static/img/canvas/sparse_shepards_pow8.png)
puissance 8.0
---|---|---|---|---
Comme vous pouvez le voir, les « taches de couleur » s'étendent, de points très nets, à des taches arrondies, jusqu'à de grandes zones de couleur. À des niveaux de puissance très élevés, elle finit par reproduire le même motif que la méthode de sparse color Voronoi. Ce -define n'affecte pas seulement Shepards Sparse Color, mais aura aussi des effets similaires sur la méthode de distorsion Shepards, qui repose sur des cartes de déplacement calculées, générées par la méthode de sparse color. Il n'affecte toutefois pas la méthode de sparse color Inverse, qui utilise toujours un niveau de puissance de 1.0.
Résumé des méthodes de sparse color
Voici une reprise des diverses images « [-sparse-color](https://imagemagick.org/command-line-options/#sparse-color) » à 4 points, à des fins de comparaison. ![[IM Output]](../static/img/canvas/sparse_voronoi.gif)
Voronoi | ![[IM Output]](../static/img/canvas/sparse_voronoi_blur.png)
Voronoi (floutée) | ![[IM Output]](../static/img/canvas/sparse_shepards.png)
Shepards | ![[IM Output]](../static/img/canvas/sparse_inverse.png)
Inverse | ![[IM Output]](../static/img/canvas/sparse_bilinear.png)
Bilinear
---|---|---|---|---
Et voici un résumé des diverses méthodes à 3 points. ![[IM Output]](../static/img/canvas/sparse_voronoi_3pt.gif)
Voronoi | ![[IM Output]](../static/img/canvas/sparse_voronoi_blur_3pt.png)
Voronoi (floutée) | ![[IM Output]](../static/img/canvas/sparse_shepards_3pt.png)
Shepards | ![[IM Output]](../static/img/canvas/sparse_inverse_3pt.png)
Inverse | ![[IM Output]](../static/img/canvas/sparse_barycentric.png)
Barycentric
---|---|---|---|---
Pour l'instant, seules les méthodes '[Voronoi](#voronoi)', '[Shepards](#shepards)' et '[Inverse](#inverse)' conviennent à plus de quatre points. D'autres méthodes « [-sparse-color](https://imagemagick.org/command-line-options/#sparse-color) » sont prévues. Si vous avez des idées, envoyez-les-moi par e-mail.
Canal et Sparse Color
L'opérateur « [-sparse-color](https://imagemagick.org/command-line-options/#sparse-color) » est affecté par le réglage « [-channel](https://imagemagick.org/command-line-options/#channel) », ce qui signifie que vous pouvez utiliser ce réglage pour en limiter les effets à un seul canal, ou l'étendre au canal de transparence. Vous pouvez aussi utiliser le réglage « [-channel](https://imagemagick.org/command-line-options/#channel) » pour accélérer le traitement des images en niveaux de gris en n'opérant que sur un seul canal, puis en effectuant un « [-separate](https://imagemagick.org/command-line-options/#separate) » de ce canal (voir Channel Handling pour plus de détails). Par exemple… |
magick -size 100x100 xc: -channel G -sparse-color Shepards \
'30,10 gray70 10,80 black 70,60 white 80,20 gray(33.3333%)' \
-separate +channel -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_gray.gif
![[IM Output]](../static/img/canvas/sparse_shepards_gray.gif)
Depuis IM v6.6.8-5, les canaux non modifiés sont préservés, de sorte que vous pouvez désormais utiliser Sparse Color avec le réglage « [-channel](https://imagemagick.org/command-line-options/#channel) » pour ajouter un dégradé transparent à n'importe quelle image, rapidement et facilement. Par exemple, j'ajoute ici un Diagonal Gradient transparent, aligné de sorte qu'une transparence de 50 % suive la diagonale de l'image intégrée « rose:. |
magick rose: -alpha set -channel A \
-sparse-color Barycentric \
'0,0 opaque %w,-%h opaque %w,%h transparent' \
rose_alpha_gradient.png
![[IM Output]](../static/img/canvas/rose_alpha_gradient.png)
| La couleur 'Opaque' n'est qu'un autre nom pour 'Black'. Fondamentalement, on l'utilise lorsqu'on ne s'intéresse réellement qu'à spécifier une couleur entièrement opaque, la couleur elle-même important peu. Il en va de même pour la couleur 'Transparent'. J'aurais tout aussi bien pu utiliser 'White' et 'None' respectivement.
---|---
| Avant IM v6.6.8-5, tout canal non sélectionné par le réglage « [-channel](https://imagemagick.org/command-line-options/#channel) » était réinitialisé à des valeurs nulles (noir). Cela limitait fortement son utilité effective.
---|---
Sparse Color accepte aussi des valeurs en virgule flottante normalisées à la place d'un nom de couleur. Le nombre exact de valeurs à fournir pour remplacer le nom de couleur dépend du réglage « [-channel](https://imagemagick.org/command-line-options/#channel) » courant, et du fait que ce canal soit « actif » ou non dans l'image traitée. Le plus simple est de limiter le traitement à un seul canal. Notez également que lorsqu'on utilise des nombres bruts, plutôt que des noms de couleur, les valeurs de transparence sont des valeurs « matte » (0 = opaque) et non des valeurs « alpha » (1 = opaque) (pour IMv7). Ainsi, dans l'exemple ci-dessus, j'aurais pu utiliser des nombres à la place des noms de couleur…
-channel A -sparse-color Bilinear '0,0 1.0 -%w,%h 1.0 %w,%h 0.0'
Cela peut être plus facile à gérer dans des scripts programmés, et dans les API, qui n'ont peut-être pas accès au traducteur de « colorname ».
Sparse Color comme opérateur de remplissage
L'une des raisons initiales de la création de l'opérateur Sparse Color était de pouvoir donner une image ne contenant qu'un petit nombre de points de couleur fixes, et à partir de là « remplir » le reste des couleurs indéfinies. Par exemple, j'ai ici dessiné un petit nombre de pixels. Le réglage « [+antialias](https://imagemagick.org/command-line-options/#antialias) » a été spécifiquement désactivé afin qu'aucune couleur semi-transparente ou mélangée ne soit dessinée ; ainsi, l'image ne contient que les quatre couleurs exactes spécifiées et aucune autre. |
magick -size 100x100 xc:none +antialias -fill none -strokewidth 0.5 \
-stroke Gold -draw "path 'M 20,70 A 1,1 0 0,1 80,50'" \
-stroke DodgerBlue -draw "line 30,10 50,80" \
-stroke Red -draw "circle 80,60 82,60" \
sparse_source.gif
![[IM Output]](../static/img/canvas/sparse_source.gif)
Nous pouvons maintenant extraire les quelques pixels non transparents présents dans cette image, puis remplir toutes les autres couleurs à l'aide de la méthode de sparse color multipoints, '[Shepards](#shepards)'. |
magick sparse_source.gif sparse-color:- |\
magick sparse_source.gif -alpha off \
-sparse-color shepards '@-' sparse_fill.png
![[IM Output]](../static/img/canvas/sparse_fill.png)
La commande « sed » ci-dessus prend le Enumerated Text File Format, supprime la première ligne d'en-tête ainsi que toute ligne contenant de la transparence, avant de la reformater en une liste de coordonnées de pixels et de couleurs. Cette liste est ensuite « pipelinée » vers l'opérateur Sparse Color à l'aide de l'argument spécial « @- ». Oui, ce qui précède est très astucieux, mais fonctionne. Du moins pour un très petit nombre de points. Cependant, plus il y a de points fournis, plus l'opération devient lente. C'est parce que Sparse Color est orienté « point » dans son traitement, plutôt qu'orienté image ou Morphology. J'espère à terme pouvoir fournir un ensemble de méthodes de « remplissage de trous » orientées morphologie, où vous pourrez simplement donner l'image ci-dessus telle quelle et la laisser remplir automatiquement les zones transparentes. Cette technique d'extraction de points peut être combinée avec la méthode de morphologie EdgeIn pour extraire les pixels autour des bords des objets ou des trous, de sorte que vous puissiez ensuite « remplir » l'arrière-plan ou les trous manquants (comme montré dans Morphology and Channels). Par exemple…
magick figure.gif -channel A -morphology EdgeIn Diamond
shape_edge_pixels.gif
magick shape_edge_pixels.gif txt:- |\
sed '1d; / 0) /d; s/:.* /,/;' | \
magick shape_edge_pixels.gif -alpha off \
-sparse-color shepards '@-' shape_edge_in_lights.png
magick shape_edge_in_lights.png figure.gif -composite shape_in_lights.png
Notez que l'image résultante est exactement la même que l'entrée, mais avec l'arrière-plan transparent remplacé par des « couleurs de bord » floutées par la distance. C'est pourquoi les bords de l'image sont devenus indistincts. Cette image a été spécifiquement développée pour tenter de générer de meilleures techniques de « plumage des bords ». Voir Blur Feathering et Distance Feathering pour d'autres techniques de plumage.
Sparse Color Shepards, une alternative au flou
Une alternative à l'utilisation de « [-sparse-color](https://imagemagick.org/command-line-options/#sparse-color) » consiste à prendre l'image des pixels sur un arrière-plan transparent, et à la flouter. Ensuite, la transparence est mise au rebut.
magick sparse_source.gif -channel RGBA -blur 0x15 \
-alpha off sparse_blur_simple.png
Le problème est que les couleurs d'origine ne sont pas préservées, et vous avez aussi le problème de savoir exactement quelle valeur de 'sigma ' utiliser. De plus, cela ne tient pas compte de la « proximité » de chaque couleur ; ainsi deux pixels colorés proches l'un de l'autre (à une distance inférieure à la valeur de 'sigma ') vont se submerger mutuellement et se fondre par le flou.
Une meilleure méthode consiste à générer plusieurs couches d'images floutées avec des valeurs de 'sigma ' progressivement plus petites, et l'image originale non floutée par-dessus.
for sigma in 64 32 16 8 4 2 1 0; do
magick sparse_source.gif -depth 16 \
-channel RGBA -blur 0x$sigma miff:-
done |
magick - -background none -flatten -alpha off sparse_blur_layered.png
Cette technique de flou en couches est équivalente au résultat d'une méthode '[Shepards](#shepards)' sur la même image ; ce n'est pas aussi exact, mais c'est très proche. Elle est toutefois susceptible d'être bien plus rapide lorsqu'un grand nombre de pixels d'entrée sont impliqués, car elle est orientée image (morphologie) plutôt que calculée à l'aide de points individuels. Une autre méthode de flou en couches consiste à utiliser Resize pour générer une « pyramide » d'images floutées. Cette technique est détaillée dans Large Blurs using Resize. |
magick sparse_source.gif \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
-layers RemoveDups -filter Gaussian -resize 100x100\! -reverse \
-background None -flatten -alpha off sparse_blur_pyramid.png
![[IM Output]](../static/img/canvas/sparse_blur_pyramid.png)
Cela fonctionne très rapidement avec de très grandes images sans nécessiter de grandes valeurs de 'sigma ' (et donc très lentes) pour chacune des étapes de flou. Essentiellement, cela utilise une technique de redimensionnement d'image plus rapide pour générer les couches floutées de l'exemple précédent. Ce n'est pas aussi exact, mais cela génère une bonne approximation du résultat correct. Cela fonctionne toutefois le mieux pour des images carrées, dont la taille est une puissance de deux, sinon la précision sera moindre. L'opérateur spécial « [-layers](https://imagemagick.org/command-line-options/#layers) RemoveDups » ci-dessus supprimera toutes les images superflues « à pixel moyen unique » qui ont été générées par les multiples opérations « clone-resize ». Les images sont ensuite redimensionnées à leur taille d'origine à l'aide d'un Gaussian Resize Filter (l'équivalent d'un flou). L'ordre des images est alors inversé afin de placer l'original par-dessus, et les couches plus floues en dessous, avant de tout aplatir comme précédemment. Cela a l'avantage de ne nécessiter qu'une seule lecture de l'image, en effectuant tout le travail en une seule commande. Cela fonctionne aussi très rapidement même pour de grandes images, d'autant que le redimensionnement ne fait que diviser l'image par deux à chaque étape, évitant ainsi le flou lent avec un très grand sigma. Le seul inconvénient de cette méthode est que vous devrez avoir une idée approximative de la taille d'origine de l'image pour restaurer les images « floutées », et pour obtenir au moins une idée approximative du nombre de clones redimensionnés à générer (Log2 de la plus grande dimension, plus 1). Cependant, en abuser sur le nombre de clones de redimensionnement n'est pas un gros coup de performance, car le redimensionnement devient simplement une « no-op » lorsque l'image d'entrée a déjà été réduite à l'image minimale d'un pixel. Les couches d'« images redimensionnées » superflues et inutiles sont ensuite traitées automatiquement à l'aide de « [-layers](https://imagemagick.org/command-line-options/#layers) RemoveDups ». Le seul vrai problème est la possibilité que les images redimensionnées se « désynchronisent » lors du traitement d'une image dont la taille n'est pas une puissance de deux. On ne sait pas à quel point ce problème est grave, mais il ne devrait pas être trop important, car ces images sont aussi les plus floutées. Bien entendu, cela présente toujours le problème de « fuite » de la méthode '[Shepards](#shepards)', alors examinons ce problème plus en détail.
La méthode Shepards « fuit »
La méthode '[Shepards](#shepards)' n'a aucune compréhension des « frontières », et de ce fait les couleurs situées de l'autre côté d'une certaine « ligne de couleur » fuiront, ou « transperceront » au-delà de cette ligne. Finalement, à grande distance, vous obtiendrez une pure couleur moyenne de tous les pixels. Ce n'est pas toujours un résultat souhaitable (bien qu'il le soit dans certains cas). Dans cet exemple, plus la courbe 'Red' se rapproche de la ligne 'White', plus la couleur « fuira » à travers les deux lignes jusqu'au côté opposé en produisant une couleur rose. |
magick -size 100x100 xc:none +antialias -fill none -strokewidth 0.5 \
-stroke Red -draw "path 'M 26,0 A 55,61 0 0,1 26,100'" \
-stroke White -draw "line 50,0 50,100" \
sparse_lines_near_source.gif
magick sparse_lines_near_source.gif txt:- |\
sed '1d; / 0) /d; s/:.* /,/;' |\
magick -size 100x100 xc: -sparse-color shepards '@-' \
sparse_lines_near.png
![[IM Output]](../static/img/canvas/sparse_lines_near.png)
Cette fuite de couleurs est le principal problème de l'utilisation de la méthode Shepards pour le « remplissage de trous », surtout lorsque plusieurs trous sont impliqués, car les couleurs associées à un trou peuvent et vont fuir dans un trou tout à fait différent et en affecter les couleurs. Et vice versa. C'est la compréhension des frontières qui constitue la différence entre la méthode Shepards et une autre forme de « remplissage de trous » de couleur connue sous le nom de « diffusion de couleur ». Fondamentalement, avec la « diffusion de couleur », les couleurs ne peuvent pas traverser une ligne d'une autre couleur définie. Cela s'obtient en limitant l'effet aux seules couleurs en « ligne de vue », ou à celles qui fuient autour de l'extérieur d'un bord. Cela nécessite d'utiliser la distance aux couleurs les plus proches pour limiter les couleurs qui influencent un pixel. Un usage majeur de la « diffusion de couleur » est présenté sur le site web Diffusion Curves. Non seulement il fait un usage intensif de la diffusion de couleur, mais il comprend aussi des informations sur les techniques permettant de générer des diffusions très rapidement. J'espère implémenter cela dans ImageMagick à un moment donné dans le futur.
Images plasma
Dégradés plasma
Alors que les dégradés fournissent une plage de couleurs continue, un autre opérateur de création d'image, « plasma: », fournit un autre type de dégradé. Un type idéalement adapté à la génération d'un arrière-plan de couleur aléatoire pour vos images. Tout d'abord, je dois signaler que « plasma: » est une image aléatoire. De ce fait, elle peut produire et produira une image différente à chaque exécution. Par exemple, nous générons ici trois images plasma « standard » distinctes, et chaque image est différente des autres, même si la même commande a été utilisée pour les générer.
magick -size 100x100 plasma: plasma1.jpg
magick -size 100x100 plasma: plasma2.jpg
magick -size 100x100 plasma: plasma3.jpg
Vous pouvez aussi voir que les images plasma sont également un type de dégradé de couleurs aléatoire et, comme « gradient: », commencent par du blanc en haut et du noir en bas. Ce qui n'est pas bien documenté, c'est que vous pouvez spécifier une couleur pour le dégradé plasma exactement de la même manière que pour les dégradés linéaires ci-dessus.
magick -size 100x100 plasma:blue plasma_range1.jpg
magick -size 100x100 plasma:yellow plasma_range2.jpg
magick -size 100x100 plasma:green-yellow plasma_range3.jpg
magick -size 100x100 plasma:red-blue plasma_range4.jpg
magick -size 100x100 plasma:tomato-steelblue plasma_range5.jpg
Vous pouvez aussi voir que les couleurs de tons moyens comme 'tomato' et 'steelblue' ont tendance à mieux fonctionner que les couleurs pures comme 'red' et 'blue'. En utilisant deux fois la même couleur avec plasma, vous pouvez produire un arrière-plan à dominante de cette couleur, mais avec des éclaboussures aléatoires de couleurs proches de celles des couleurs d'origine.
magick -size 100x100 plasma:black-black plasma_black.jpg
magick -size 100x100 plasma:grey-grey plasma_grey.jpg
magick -size 100x100 plasma:white-white plasma_white.jpg
magick -size 100x100 plasma:yellow-yellow plasma_yellow.jpg
magick -size 100x100 plasma:tomato-tomato plasma_tomato.jpg
magick -size 100x100 plasma:steelblue-steelblue plasma_steelblue.jpg
Là encore, comme vous pouvez le voir, les couleurs de tons moyens généreront plus de variétés de couleur dans l'image résultante qu'une couleur extrême, comme le noir, le blanc ou le jaune. La plasma 'grey' ci-dessus est particulièrement belle, donnant un effet irisé de type « nacre » ; fondamentalement parce que le gris dispose d'une totale liberté dans les couleurs que « plasma: » va générer. Normaliser une plasma parfaitement gris à 50 % produira une image plasma multicolore particulièrement uniforme, sur toute la plage de couleurs, y compris le blanc et le noir. |
magick -size 100x100 plasma:grey50-grey50 -auto-level plasma_grey_norm.jpg
![[IM Output]](../static/img/canvas/plasma_grey_norm.jpg)
Autrement, vous pouvez simplement élargir le contraste des couleurs pour les rendre plus vives, mais sans aller dans les extrêmes. |
magick -size 100x100 plasma:grey50-grey50 \
-sigmoidal-contrast 8x50% plasma_grey_contrast.jpg
![[IM Output]](../static/img/canvas/plasma_grey_contrast.jpg)
Comparez cette image avec les images de « plasma fractal » ci-dessous.
Plasma fractal
Le générateur de plasma dispose aussi d'un mode fractal spécial, qui produit des effets très colorés. Les couleurs générées sont rehaussées pour produire des changements de couleur plus exagérés.
magick -size 100x100 plasma:fractal plasma_fractal1.jpg
magick -size 100x100 plasma:fractal plasma_fractal2.jpg
magick -size 100x100 plasma:fractal plasma_fractal3.jpg
En fait, c'est très similaire aux images plasma à couleur constante que nous avons déjà vues, et de fait elles sont générées de la même manière, mais avec des changements de couleur plus prononcés.
Je trouve souvent que les images plasma sont un peu « bruitées ». De ce fait, elles bénéficieront généralement d'un léger lissage à l'aide de « [-blur](https://imagemagick.org/command-line-options/#blur) ». J'ai ici lissé le bruit de l'image plasma centrale ci-dessus. |
magick plasma_fractal2.jpg -blur 0x2 plasma_smooth.jpg
![[IM Output]](../static/img/canvas/plasma_smooth.jpg)
Vous pouvez utiliser « [-paint](https://imagemagick.org/command-line-options/#paint) » pour créer des taches de couleur aléatoires. |
magick plasma_fractal2.jpg -blur 0x1 -paint 8 plasma_paint.jpg
![[IM Output]](../static/img/canvas/plasma_paint.jpg)
Ou rendez les couleurs plus prononcées et circulaires à l'aide de l'opérateur d'image « [-emboss](https://imagemagick.org/command-line-options/#emboss) », après avoir utilisé « [-blur](https://imagemagick.org/command-line-options/#blur) » pour supprimer le bruit de bas niveau. |
magick plasma_fractal2.jpg -blur 0x5 -emboss 2 plasma_emboss.jpg
![[IM Output]](../static/img/canvas/plasma_emboss.jpg)
En utilisant un « [-blur](https://imagemagick.org/command-line-options/#blur) » suivi d'un « [-sharpen](https://imagemagick.org/command-line-options/#sharpen) », vous pouvez produire un motif de couleurs plus pastel que celui produit avec « [-emboss](https://imagemagick.org/command-line-options/#emboss) ». |
magick plasma_fractal2.jpg -blur 0x5 -sharpen 0x15 plasma_sharp.jpg
![[IM Output]](../static/img/canvas/plasma_sharp.jpg)
Je trouve en fait que générer un dégradé plasma tourbillonné est particulièrement beau comme motif d'arrière-plan. |
magick -size 160x140 plasma:fractal \
-blur 0x2 -swirl 180 -shave 20x20 plasma_swirl.jpg
Plasma en niveaux de gris
Or, le générateur de plasma générera toujours de la couleur, même sur une couleur unie noir pur. Il est cependant souvent utile de générer une plasma en niveaux de gris pure. Eh bien, il y a deux façons simples de faire cela. La plus simple consiste à prendre l'image plasma et à la convertir en niveaux de gris. |
magick -size 100x100 plasma:fractal -blur 0x2 \
-colorspace Gray plasma_greyscale.jpg
![[IM Output]](../static/img/canvas/plasma_greyscale.jpg)
Une autre façon consiste à copier l'un des canaux de couleur sur les deux autres, pour un effet plus fort, en une seule couche. |
magick -size 100x100 plasma:fractal -blur 0x2 \
-channel G -separate plasma_grey_copy.jpg
![[IM Output]](../static/img/canvas/plasma_grey_copy.jpg)
Une dernière technique consiste à utiliser « [-shade](https://imagemagick.org/command-line-options/#shade) » sur la plasma. |
magick -size 100x100 plasma:fractal -blur 0x5 \
-shade 120x45 -auto-level plasma_grey_shade.jpg
![[IM Output]](../static/img/canvas/plasma_grey_shade.jpg)
Vous penseriez probablement obtenir beaucoup d'effets de lumière et d'ombre, mais la plasma brute est si aléatoire que « [-shade](https://imagemagick.org/command-line-options/#shade) » ne semble produire qu'un effet de « plasma plus tacheté ». Au lieu d'utiliser une plasma fractale, avec ses changements de couleur hautement exagérés, vous pouvez créer une plasma en niveaux de gris à l'aide de la méthode plasma à couleur constante. Comme effet secondaire, cette méthode vous permet aussi de contrôler la luminosité globale de l'image plasma en niveaux de gris générée.
magick -size 100x100 plasma:black-black \
-blur 0x2 -colorspace Gray plasma_grey0.jpg
magick -size 100x100 plasma:grey25-grey25 \
-blur 0x2 -colorspace Gray plasma_grey1.jpg
magick -size 100x100 plasma:grey50-grey50 \
-blur 0x2 -colorspace Gray plasma_grey2.jpg
magick -size 100x100 plasma:grey75-grey75 \
-blur 0x2 -colorspace Gray plasma_grey3.jpg
magick -size 100x100 plasma:white-white \
-blur 0x2 -colorspace Gray plasma_grey4.jpg
Si ce n'est pas assez marqué, utilisez la méthode de copie de canal pour mettre l'image plasma en niveaux de gris.
magick -size 100x100 plasma:black-black \
-blur 0x2 -channel G -separate plasma_grey5.jpg
magick -size 100x100 plasma:grey25-grey25 \
-blur 0x2 -channel G -separate plasma_grey6.jpg
magick -size 100x100 plasma:grey50-grey50 \
-blur 0x2 -channel G -separate plasma_grey7.jpg
magick -size 100x100 plasma:grey75-grey75 \
-blur 0x2 -channel G -separate plasma_grey8.jpg
magick -size 100x100 plasma:white-white \
-blur 0x2 -channel G -separate plasma_grey9.jpg
Ces images de plasma en niveaux de gris sont très utiles pour un traitement ultérieur et permettent de générer d'autres effets d'image. Par exemple, consultez la page sur les Background Images (images de fond) pour un très grand nombre d'exemples où le fractal de plasma a servi à produire de nombreux effets intéressants.
Amorcer ou reproduire une image de plasma
Rappelez-vous que « plasma: » peut produire des zones de noir presque pur ou de blanc presque pur, ou de toute autre couleur (bien qu'elle ne soit probablement pas pure). Et s'il est peu probable d'obtenir une image entièrement d'une seule couleur, cela reste un résultat possible. C'est pourquoi, lorsque vous obtenez un bon résultat, vous pourriez vouloir l'enregistrer pour le réutiliser plus tard. De ce fait, les scripts qui utilisent des images de plasma peuvent inclure des options pour générer et réutiliser de telles images aléatoires. Autrement dit, vous pourriez vouloir séparer la génération de l'image de plasma des autres parties qui l'utilisent, afin d'en permettre la réutilisation. Une technique plus simple consiste toutefois à « amorcer » ou initialiser le générateur de nombres aléatoires d'IM pour que « plasma: » génère la même image « aléatoire ». De cette façon, vous pouvez régler un script ou un programme pour produire encore et encore une coloration ou un effet réussi ou intéressant. |
magick -size 100x100 -seed 4321 plasma: plasma_seeded.jpg
![[IM Output]](../static/img/canvas/plasma_seeded.jpg)
L'image ci-dessus ne changera jamais, donc tant que je ne modifie pas le nombre de « [-seed](https://imagemagick.org/command-line-options/#seed) », j'aurai toujours une zone « rouge » dans le coin inférieur droit. Fait intéressant, utiliser la même amorce avec des dégradés de couleurs d'initialisation différents peut produire un ensemble d'images qui, tout en étant aléatoires, se ressemblent par leur motif interne.
magick -size 100x100 -seed 4321 plasma:grey-grey plasma_rnd1.jpg
magick -size 100x100 -seed 4321 plasma:white-blue plasma_rnd2.jpg
magick -size 100x100 -seed 4321 plasma:green-yellow plasma_rnd3.jpg
magick -size 100x100 -seed 4321 plasma:red-blue plasma_rnd4.jpg
magick -size 100x100 -seed 4321 plasma:tomato-steelblue plasma_rnd5.jpg
Comme vous pouvez le voir, le même motif de couleurs est présent dans toutes les images ci-dessus, même si la base de couleur sous-jacente peut mettre en évidence ou masquer des parties du motif partagé. Un dernier mot d'avertissement. D'autres opérateurs d'IM peuvent également utiliser le générateur de nombres aléatoires, comme la fonction « rand() » de « [-fx](https://imagemagick.org/command-line-options/#fx) », le réglage « random » de « [-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel) », l'opérateur de tramage « [-random-threshold](https://imagemagick.org/command-line-options/#random-threshold) » et l'opérateur « [-noise](https://imagemagick.org/command-line-options/#noise) ». Il est donc judicieux d'amorcer le générateur juste avant votre usage spécifique du générateur de nombres aléatoires. Depuis IM v6.3.4-3, vous pouvez aussi réinitialiser aléatoirement le générateur avec « [+seed](https://imagemagick.org/command-line-options/#seed) ». Placer ce réglage après votre « plasma amorcé » garantit donc que les opérateurs ultérieurs génèrent correctement un résultat aléatoire si vous le souhaitez. Par défaut, l'amorce est initialisée aléatoirement au démarrage d'IM, si bien que vous n'avez normalement pas besoin de la réinitialiser vous-même avec « [+seed](https://imagemagick.org/command-line-options/#seed) » pour obtenir un résultat aléatoire.
Problèmes liés à l'utilisation de Plasma
Un problème à éviter avec les images « plasma: » est de les générer avec un rapport d'aspect élevé. Cela tend à déformer les effets de couleur habituels du plasma, en étirant les couleurs en stries semblables à des aiguilles.
magick -size 200x50 plasma: plasma_high_aspect.jpg
Il n'existe pas de solution simple à cela, donc à moins que ce soit précisément ce que vous voulez, la prudence est de mise. Il y a aussi une nette distorsion diagonale du coin supérieur gauche vers le coin inférieur droit dans l'image de plasma, qui ne devrait pas exister. Autrement dit, il y a une sorte de défaut de « biais spatial » dans l'algorithme. Par exemple, comme l'a fait remarquer Thomas Maus
magick -size 60x60 plasma: \( +clone -flop \) +append plasma_flaw.jpg
Cela ne devrait pas se produire. Mais le problème semble trop profond pour pouvoir être corrigé sans réécrire entièrement, pour ainsi dire, toute la fonction de génération du plasma.
Images aléatoires
Bruit aléatoire brut
Depuis IM v6.3.5, vous pouvez générer une image purement aléatoire à partir d'une image existante à l'aide du générateur de bruit, « [+noise](https://imagemagick.org/command-line-options/#noise) » avec la méthode « Random ». |
magick -size 100x100 xc: +noise Random random.png
![[IM Output]](../static/img/canvas/random.png)
Si votre IM est plus ancien que cela, vous pouvez toujours générer une image de bruit purement aléatoire à l'aide du DIY FX Operator, plus lent, « [-fx](https://imagemagick.org/command-line-options/#fx) ». |
magick -size 100x100 xc: -fx 'rand()' random_fx.png
![[IM Output]](../static/img/canvas/random_fx.png)
Ou, pour la rapidité, vous pouvez utiliser l'opérateur « [-spread](https://imagemagick.org/command-line-options/#spread) » pour aléatoiriser un dégradé (séparément pour les trois canaux de couleur) ou en utilisant une autre image. |
magick -size 100x100 gradient: -separate \
-virtual-pixel tile -spread 200 -combine random_spread.png
![[IM Output]](../static/img/canvas/random_spread.png)
Le résultat peut sembler très aléatoire, mais il produira une plage de couleurs (ou simplement de valeurs de couleur) plus contrôlée.
Mouchetures aléatoires (poussière de pixels)
Générer des images de pixels aléatoires épars peut également s'avérer très utile. Rappelez-vous simplement que chacun des trois Color Channels (canaux de couleur) d'une image aléatoire peut être considéré comme une image aléatoire distincte en niveaux de gris, et que ces canaux peuvent être fusionnés de diverses manières. Par exemple, vous générez un masque de points aléatoires en appliquant d'abord un Thresholding (seuillage) à un canal de couleur (« G », le canal vert), puis en l'isolant sous forme d'image en niveaux de gris. |
magick random.png -channel G -threshold 5% -separate \
+channel -negate random_mask.png
![[IM Output]](../static/img/canvas/random_mask.png)
Comme chaque couleur est une valeur aléatoire linéaire, le pourcentage de seuil utilisé ci-dessus définit directement la densité de pixels sélectionnés. Vous pouvez aller plus loin et utiliser un canal de couleur (« G », le canal vert) pour sélectionner des valeurs aléatoires dans un autre canal de couleur (« R », le canal rouge), au moyen de diverses méthodes de Image Composition (composition d'images).
magick random.png -channel G -threshold 5% -negate \
-channel RG -separate +channel \
-compose Multiply -composite random_black.png
magick random.png -channel G -threshold 5% \
-channel RG -separate +channel \
-compose Screen -composite random_white.png
magick random.png -channel G -threshold 5% -negate \
-channel RG -separate +channel \
-compose CopyOpacity -composite random_trans.png
Ces types d'images sont directement utilisables pour générer des Glitter Animations (animations scintillantes). Mais un traitement supplémentaire, en particulier sur la version à fond noir, vous permettra d'agrandir les points en fonction de leur intensité en niveaux de gris, ou de générer des stries et des éclats en étoile à partir de ces points. Pour des exemples, voir Star Generators. Comme pour les Seeded Plasma Images, vous pouvez également utiliser le réglage « [-seed](https://imagemagick.org/command-line-options/#seed) » pour pré-initialiser le générateur de nombres aléatoires. Cela vous permet de générer de façon reproductible la ou les mêmes images aléatoires pour une machine donnée, tout comme pour les images de plasma.
Images aléatoires floutées (blobs aléatoires)
Vous pouvez certes utiliser directement des images aléatoires pour créer des effets mouchetés, mais les images purement aléatoires ne sont généralement pas très utiles. En revanche, en Blurring (floutant) une image purement aléatoire, vous introduisez un certain ordre de « voisinage », de sorte que les pixels proches deviennent liés. Par exemple, ici je floute une seule image aléatoire, ce qui amène les valeurs aléatoires à produire de plus grands « blobs » ou des couleurs marbrées.
magick random.png -virtual-pixel tile -blur 0x1 -auto-level random_1.png
magick random.png -virtual-pixel tile -blur 0x3 -auto-level random_3.png
magick random.png -virtual-pixel tile -blur 0x5 -auto-level random_5.png
magick random.png -virtual-pixel tile -blur 0x10 -auto-level
random_10.png
magick random.png -virtual-pixel tile -blur 0x20 -auto-level
random_20.png
Notez toutefois que sans le Virtual Pixel Setting, l'opérateur « [-blur](https://imagemagick.org/command-line-options/#blur) » présentera de forts effets de bord, qu'il vaut mieux éviter. En prime, en changeant le réglage « [-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel) » en « tile », l'image aléatoirisée reste juxtaposable, les couleurs s'enroulant au-delà des bords de l'image. Cette capacité de juxtaposition n'est actuellement pas possible avec une Plasma Images aléatoire, et c'est une conséquence inhérente au fait que les images purement aléatoires sont si aléatoires au départ. Teintes aléatoires floutées Une conversion particulière d'une image de bruit aléatoire floutée que j'ai trouvée particulièrement plaisante consiste à mapper les valeurs sur les teintes de couleur HSB. |
magick random_10.png -set colorspace HSB \
-channel GB -evaluate set 100% +channel \
-colorspace RGB random_hues_cyan.png
![[IM Output]](../static/img/canvas/random_hues_cyan.png)
Le problème de ce qui précède est que le flou tend à créer des taches de rouge-jaune (valeurs basses) et de rouge-magenta (valeurs hautes), avec des bandes de vert, de cyan et de bleu entre elles. C'est simplement une conséquence de la manière dont les valeurs de teinte ont été floutées et mises à niveau. La solution idéale serait une sorte de flou modulaire, qui prendrait en compte la nature cyclique des valeurs de teinte. Cependant, un tel opérateur n'est pas disponible actuellement, et ne le sera peut-être jamais. La meilleure solution que je connaisse consiste simplement à additionner les trois canaux aléatoires de l'image (au moyen de la Modulus-Add Composition) de façon à étendre la plage de valeurs. Cela a aussi pour effet secondaire de rendre les taches floutées plus petites, mais au moins vous obtenez désormais des couleurs arc-en-ciel à plage plus dynamique. Quelqu'un a-t-il une meilleure idée ? |
magick random_10.png -separate -background white \
-compose ModulusAdd -flatten -channel R -combine +channel \
-set colorspace HSB -colorspace RGB random_hues.png
![[IM Output]](../static/img/canvas/random_hues.png)
Pour d'autres méthodes de traitement d'une image aléatoire, voir Plasma Images ci-dessus, ainsi que Generating Backgrounds. Gris aléatoires floutés Comme vous pouvez le voir d'après ce qui précède, vous obtenez une image comportant divers blobs de couleurs primaires. C'est parce que chaque canal est traité complètement séparément des autres, comme des images en niveaux de gris. Extrayons l'un des canaux de chacune des images ci-dessus pour que vous puissiez voir la structure de l'image floutée…
magick random.png -channel G -separate random_0_gray.png
magick random_1.png -channel G -separate random_1_gray.png
magick random_3.png -channel G -separate random_3_gray.png
magick random_5.png -channel G -separate random_5_gray.png
magick random_10.png -channel G -separate random_10_gray.png
magick random_20.png -channel G -separate random_20_gray.png
La première chose que vous devriez remarquer, c'est que l'image contient généralement (mais pas toujours) des quantités à peu près égales de zones noires et blanches. Vous pouvez le constater si nous appliquons un Threshold (seuil) de 50 % aux images aléatoires
magick random_0_gray.png -threshold 50% random_0_thres.png
magick random_1_gray.png -threshold 50% random_1_thres.png
magick random_3_gray.png -threshold 50% random_3_thres.png
magick random_5_gray.png -threshold 50% random_5_thres.png
magick random_10_gray.png -threshold 50% random_10_thres.png
magick random_20_gray.png -threshold 50% random_20_thres.png
Comme vous pouvez le voir, vous obtenez environ 50 % de zones blanches et 50 % de zones noires, séparées par une ligne courbe. De plus, la courbure de cette ligne varie selon la valeur « sigma » utilisée pour flouter l'image purement aléatoire. Depuis des pixels isolés générant une « neige » noire et blanche jusqu'à une séparation très uniforme (bien qu'encore aléatoire) de l'image en deux zones noire et blanche. Pour davantage d'exemples d'utilisation d'images aléatoires, voir Background Images, ou pour voir la génération de canevas aléatoires, voir Random Spots of Solid Color.
Granularité aléatoire (l'ordre dans le chaos)
Rappelez-vous maintenant que toutes les images aléatoires floutées ont été générées à partir de la même image aléatoire initiale, elles sont donc toutes liées. Mais chaque nouvelle image aléatoire générée aura un motif entièrement différent, même si les motifs se ressembleront plus ou moins par leur structure. Mais donnons d'abord un exemple complet de génération d'une « image aléatoire floutée » à partir de zéro… |
magick -size 100x100 xc: -channel G +noise Random \
-virtual-pixel Tile -blur 0x5 -auto-level \
-separate +channel random_5_gray.png
![[IM Output]](../static/img/canvas/random_5_gray.png)
Le recours intensif au réglage « [-channel](https://imagemagick.org/command-line-options/#channel) » pour limiter les opérations au canal « Green » de l'image est important, car il accélère d'un facteur 3 la génération globale de l'image. La Channel separate garantit ensuite l'obtention d'un résultat purement en niveaux de gris. Si vous le souhaitez, vous pouvez omettre les deux réglages « [-channel](https://imagemagick.org/command-line-options/#channel) », ce qui se traduira par la génération de 3 « images aléatoires floutées » complètement distinctes et différentes. L'image possède quelques caractéristiques importantes, que nous pouvons voir plus clairement si nous la divisons en trois ensembles de couleurs égaux (au moyen d'une technique appelée Posterization) : vous pouvez voir qu'à l'intérieur de chacune des zones noires et blanches, vous obtenez davantage de blobs circulaires ou « granules ». Par exemple… |
magick random_5_gray.png -ordered-dither threshold,3 random_5_blobs.png
![[IM Output]](../static/img/canvas/random_5_blobs.png)
Je voudrais d'abord souligner comment on obtient des quantités à peu près égales de zones claires et sombres au sein de l'image, mais que ces zones sont interconnectées par les couleurs grises « intermédiaires » du dégradé qui se forme entre les zones claires et sombres. Or, les blobs ou « granules » individuels varient d'une zone à l'autre à travers l'image, mais leur diamètre moyen est d'environ trois à quatre fois la valeur utilisée pour flouter l'image aléatoire initiale. Cette valeur de flou, connue sous le nom de « granularité » de l'image, est une valeur très importante, car elle représente fondamentalement la taille moyenne des structures circulaires que produit l'image aléatoire. On l'appelle parfois la « sinuosité » de l'image. Plus la valeur est grande, plus ces courbes sont grandes et lentes au sein de l'image. C'est le facteur le plus important décrivant une image aléatoire floutée, alors soyons très clairs…
La « granularité » d'une image aléatoire (ou facteur de flou)
détermine la taille des structures circulaires en son sein
Bien sûr, plus le « facteur de flou » ou « granularité » est petit, plus les courbes deviennent petites ou serrées, jusqu'à atteindre une valeur de « 0 », point auquel tous les amas ou « blobs » de l'image disparaissent, et il ne vous reste qu'un effet de « bruit », de « neige » ou de « poussière de pixels » purement aléatoire.
REMARQUE : En réalité, la taille des « granules » eux-mêmes peut varier selon le facteur de seuil utilisé pour les générer. Ce que le facteur décrit vraiment, c'est la distance moyenne entre les centres des zones blanches et noires. Plus la valeur est grande, plus la distance est grande, et plus les taches doivent être grandes et étalées pour absorber cette distance accrue. Cela devient plus évident lorsque nous commençons à examiner les Random Ripples ci-dessous.
Vous pourriez aussi essayer une opération de Solarize à 50 % avec quelques Level Adjustments supplémentaires pour extraire de l'image les granules noirs et blancs bien séparés. Par exemple, voici un exemple complet avec une granularité de « 8 » et un seuil de blob de « 25% » générant des taches blanches à partir des parties à la fois noires et blanches de l'image. |
magick -size 100x100 xc: -channel G +noise random \
-virtual-pixel tile -blur 0x8 -auto-level \
-solarize 50% -separate +channel \
-threshold 25% -negate random_granules.png
![[IM Output]](../static/img/canvas/random_granules.png)
Attention, à mesure que la valeur augmente, le temps de génération de l'image aléatoire floutée s'allonge lui aussi considérablement. De plus, lorsque la valeur atteint environ la moitié de la plus petite dimension de l'image, l'effet cesse de croître, car l'image aléatoire se stabilise en une unique tache blanche et noire. Les grandes valeurs ne sont pas recommandées.
Pour finir, on montre à gauche une Patrol Cycle Animation (animation en cycle de patrouille) résultant de la variation de la « granularité » (flou aléatoire) d'une seule image aléatoire. L'animation a été générée à l'aide du script shell « [animate_granularity](../static/img/canvas/animate_granularity) », que vous pouvez télécharger, étudier et manipuler. Notez que, la même image aléatoire servant de source, les « granules » ou taches ne se déplacent pas vraiment, mais ne font en quelque sorte que se rassembler ou s'estomper, de façon à produire de plus grands « granules » à mesure que la granularité augmente. Rappelez-vous aussi que, bien que j'aie réduit le nombre de couleurs dans l'animation, la structure de l'image aléatoire complète est en réalité un dégradé lisse entre deux ensembles de granules blancs et noirs. C'est ce dégradé qui rend l'image utile dans d'autres techniques.
Flux aléatoire (cycles d'animation)
Comme vous l'avez vu ci-dessus, les granules ou taches ne se déplacent en fait pas tant que ça. Mais pour des effets d'animation, vous voulez un motif qui évolue de façon fluide dans le temps. Et vous ne voulez pas non plus que ce motif se contente de faire des allers-retours. Enfin, vous ne voulez pas que ce motif de mouvements saute ou tressaute brusquement lorsque l'animation boucle. Ce dont nous avons besoin, c'est donc d'un moyen de générer un motif aléatoire qui se répète en douceur. Un défi de taille. De plus, comme il doit être fluide, vous devrez générer tous les motifs à partir de la même unique image aléatoire. Voici une idée qui permet de générer un tel motif aléatoire. Plutôt que de considérer chaque valeur de pixel aléatoire comme une intensité aléatoire, nous considérons cette valeur comme une valeur de « temps » définissant le moment où ce pixel est à son intensité maximale ou minimale. Autrement dit, nous transformons cette valeur en une position sur une « onde ». Ainsi, chaque pixel représente une « phase » d'une courbe sinusoïdale. Cela semble compliqué, mais en réalité ça ne l'est pas. Nous utilisons simplement la Random Image comme image source pour une Sinusoid Function. Puis, pour chaque image de la séquence temporelle, nous fixons la « phase » temporelle pour ce point particulier du cycle.
magick random.png -function Sinusoid 1,_{time}_ \
... effectuer le flou granulaire et autres traitements ...
Où « _{time}_ » varie de « 0 » à « 360 » sur l'ensemble du cycle d'animation. Le résultat est qu'au lieu que chaque pixel ait une valeur aléatoire « statique », nous en avons maintenant une qui parcourt en boucle un cycle entre le noir et le blanc sur une période de temps. Chaque pixel suivra ce même cycle, mais comme chaque pixel a une « phase » complètement différente, il évoluera indépendamment de tous les autres pixels. Autrement dit, l'image reste aléatoire, mais change en douceur avec la valeur de « temps » fournie. Pour les esprits scientifiques, cela ressemble un peu à observer la « fluctuation quantique » qui existe au niveau subatomique, où l'espace est bien loin de l'état « statique » que nous voyons aux échelles normales. D'où le nom de « Flux aléatoire ». Par exemple, générons une séquence temporelle de 12 images…
for i in `seq 0 30 359`; do
magick random.png -channel G -function Sinusoid 1,${i} \
-virtual-pixel tile -blur 0x8 -auto-level \
-separate flux_${i}.png
done
Et votre unique image aléatoire peut désormais générer toute une séquence d'images formant un cycle. Notez que l'extraction du « temps » doit avoir lieu avant tout autre traitement tel que le flou, qui est probablement la partie la plus lente de tout le processus de génération. L'autre chose à remarquer, c'est qu'à la phase « 180 » (en bas à droite), vous obtenez en fait le négatif exact de la première image (en haut à gauche). C'est-à-dire que les granules « blancs » sont devenus des granules « noirs », et vice-versa. En fait, toute la seconde moitié de l'animation est en réalité le négatif de la première moitié. Cela peut servir à réduire le temps de génération d'une simple animation « Flux aléatoire ». Comme l'image est un négatif à une phase de 180 degrés, vous constaterez que chaque granule « blanc » se déplace lentement de façon à échanger sa place avec un granule « noir » voisin. Mais comme toute la seconde moitié est un négatif de la première, il ne peut pas simplement faire des allers-retours ; il doit continuer d'avancer pour revenir à l'image d'origine, ou tourner en boucle, ou tout simplement s'estomper et réapparaître comme il convient. Autrement dit, les granules blancs et noirs se déplacent selon un cycle bien plus complexe.
À droite se trouve une animation des images ci-dessus… Le motif fluctuant est complètement aléatoire, mais change en douceur d'une image à l'autre, et lorsque l'animation boucle. Vous ne pouvez discerner ni début ni fin au résultat. Parfois vous obtenez un tourbillon de mouvement, d'autres fois on dirait que tous les blobs semblables à du « gaz » sont aspirés dans une zone sombre, ou qu'ils apparaissent et s'estompent à nouveau. Vous avez aussi des périodes de mouvements très rapides, ainsi que de mouvements très lents. C'est totalement aléatoire. En résumé : les mêmes propriétés présentes dans les Blurred Random Images sont aussi présentes dans cette animation. L'image reste une division à peu près égale entre segments blancs et noirs, et elle forme des blobs d'environ trois fois la taille du flou ou Granularity de l'image. Mais en plus de cela, vous avez la garantie que toutes les parties de l'image formeront un certain cycle entre couleurs plus claires et plus sombres, puisque la moitié du cycle est le négatif de l'autre moitié. Une chose que vous n'avez peut-être pas remarquée, c'est qu'en raison de la conversion d'une valeur linéaire aléatoire en une forme d'onde sinusoïdale, vous obtiendrez une séparation plus nette (contraste) des couleurs blanches et noires. Aussi pourriez-vous vouloir utiliser l'aspect « décontrastant » de l'opérateur Sigmoidal Contrast pour rendre l'image résultante moins semblable à des « blobs », et rehausser le dégradé entre les granules, plutôt que les granules eux-mêmes. Or, ce n'est là qu'un point de départ pour ce que vous pouvez faire avec une animation aléatoire cyclique. Tout ce que vous pouvez faire avec une Random Image, comme décrit dans Generating Backgrounds, peut également s'appliquer à une « animation de flux aléatoire » Par exemple, montrons juste le mouvement des seuls granules « blancs »… |
magick flux_anim.gif -threshold 70% flux_thres_anim.gif
![[IM Output]](../static/img/canvas/flux_thres_anim.gif)
Ou générons des filaments électriques changeants qui s'écoulent lentement sur l'image. |
magick flux_anim.gif \
-sigmoidal-contrast 30x50% -solarize 50% -auto-level \
-set delay 20 filaments_anim.gif
![[IM Output]](../static/img/canvas/filaments_anim.gif)
Notez qu'en raison du fait que la moitié du cycle est une négation de la première moitié, et parce que nous utilisons un Solarize pour replier de moitié les couleurs blanches et noires, le cycle se répète en réalité deux fois au cours d'un seul cycle d'animation. Il faudrait vraiment beaucoup plus d'images pour supprimer certains des changements très rapides qui se produisent.
Pour rendre le mouvement moins prévisible sur une séquence cyclique plus longue, vous pouvez aussi utiliser du Gradient Math pour combiner plusieurs cycles sinusoïdaux, issus de plusieurs images aléatoires, ou même en utilisant simplement les autres canaux de couleur de la même image aléatoire.
FUTURE : Créer des cycles « harmoniques » de longue durée encore moins prévisibles.
Ondulations aléatoires
En ajoutant une autre variation à une Blurred Random Image, nous pouvons ajouter un niveau de complexité supplémentaire qui rend ces images bien plus utiles, et nous donne une autre variable de contrôle au-delà de sa Granularity. Mais vous devez d'abord vous rappeler que l'image aléatoire ne se compose pas seulement de zones claires et sombres, mais contient aussi une pente entre ces zones. En utilisant cette pente comme entrée de la Sinusoid Function, vous pouvez générer des ondulations entre les taches de l'image. Notez que la différence essentielle entre cet usage de la Sinusoid Function et les exemples précédents de Random Flux est que, cette fois, la fonction est appliquée à l'image APRÈS son lissage par le flou, et non avant. Aussi, dans ce cas, c'est la valeur de « Fréquence », et non la seconde valeur de « Phase », qui est la plus importante. Par exemple…
magick random_10_gray.png -function Sinusoid 1,90 ripples_1.png
magick random_10_gray.png -function Sinusoid 2,90 ripples_2.png
magick random_10_gray.png -function Sinusoid 3,90 ripples_3.png
magick random_10_gray.png -function Sinusoid 4,90 ripples_4.png
Comme vous pouvez le voir, plus la « Fréquence » de la Sinusoid Function est grande, plus d'ondulations sont ajoutées dans le dégradé entre les « granules ». Une « Fréquence » de « 1 » transformera essentiellement en blanc les « blobs » clairs et sombres de l'image source, en laissant un écart sombre entre eux. Une « Fréquence » de « 2 » comprime une « crête » ou « ondulation » supplémentaire dans cet écart sombre. À mesure que la fréquence augmente, vous obtenez de plus en plus d'« ondulations » entre les zones les plus claires et les plus sombres de l'image d'origine, la rendant de plus en plus complexe. À mesure que le nombre de crêtes augmente, vous pouvez perdre de vue les « blobs » ou « granules » d'origine de l'image. Vous pouvez corriger cela en modifiant le dégradé avant d'ajouter les ondulations, soit en « écrêtant » le dégradé au moyen d'un Level Adjustment, soit en comprimant les tons moyens au moyen du Sigmoidal Contrast. Cela donnera aux « granules » une certaine masse ou surface, offrant des zones de « calme » entre les ondulations.
magick random_10_gray.png -level 25% random_enhanced.png
magick random_enhanced.png -function Sinusoid 4,90 ripples_4e.png
magick random_10_gray.png -sigmoidal-contrast 10,50% random_sigmoidal.png
magick random_sigmoidal.png -function Sinusoid 4,90 ripples_4s.png
Les deux méthodes ont des avantages et des inconvénients, mais elles agrandissent en substance les granules, sans toutefois agrandir la distance entre les ensembles de granules blancs et noirs. L'effet secondaire en est bien sûr une compression des ondulations entre les deux ensembles de granules.
La seconde valeur « 90 » utilisée dans les exemples ci-dessus est la « Phase » de la Sinusoid Function. Elle détermine la couleur que prendra le granule « noir » de l'image source dans l'image « ondulée ».
magick random_enhanced.png -function Sinusoid 3,0 ripples_3e000.png
magick random_enhanced.png -function Sinusoid 3,90 ripples_3e090.png
magick random_enhanced.png -function Sinusoid 3,180 ripples_3e180.png
magick random_enhanced.png -function Sinusoid 3,270 ripples_3e270.png
La couleur du granule « blanc » dépendra à la fois de la « Phase » et de la fraction de la « Fréquence » appliquée. Une valeur entière de « Fréquence » fera varier ensemble la couleur des granules blancs et noirs (selon la « Phase »). Ainsi, avec une phase de « 90 », les deux seront blancs. Cependant, si vous appliquez une valeur fractionnaire de « Fréquence » de, disons, « 0.5 », le granule « source blanche » sera le négatif du granule « source noire » (tel que déterminé par la « Phase »). |
magick random_enhanced.png -function Sinusoid 3.5,90 ripples_3.5e.png
![[IM Output]](../static/img/canvas/ripples_3.5e.png)
Notez que pour les angles de « Phase » « gris », l'un des granules est entouré d'un anneau blanc, tandis que l'autre est entouré d'un anneau noir. Si une valeur de « Fréquence » avec une fraction « 0.5 » est utilisée, la première ondulation autour de chaque tache sera entièrement blanche ou entièrement noire, selon la « Phase » utilisée. | _Les « Fréquences » autres que des entiers ou « 0.5 » ne sont pas recommandées, car les deux ensembles de granules ne seront pas synchronisés d'une manière ou d'une autre.
De même, les phases autres que des multiples de 90 degrés ne sont pas recommandées, sauf pour générer une « animation d'ondulations » (voir ci-dessous).
Une valeur de phase de « 0 » est recommandée pour générer des « cartes de dispersion » (voir ci-dessous), car elle engendre des distorsions minimales à l'intérieur des zones de « granules » rehaussées.
---|---
Comme précédemment dans Random Flux, vous pouvez modifier la « _Phase » dans le temps de façon à générer une animation des ondulations se déplaçant d'un ensemble de granules à l'autre. Cela fonctionne particulièrement bien sans aucun rehaussement de contraste. |
for i in `seq 0 30 359`; do
magick random_10_gray.png -function Sinusoid 3.5,${i} miff:-
done |
magick miff:- -set delay 15 -loop 0 ripples_anim.gif
![[IM Output]](../static/img/canvas/ripples_anim.gif)
REMARQUE : la technique utilisée ci-dessus est connue sous le nom de « MIFF: en pipeline » et elle est possible parce que le format de fichier MIFF:" peut simplement « concaténer » des images pour générer un fichier à images multiples. Un point à noter est que cette animation semble changer bien plus lentement que la Flux Animation que nous avons créée plus haut. C'est parce que, sur un cycle d'animation, une ondulation ne parcourt qu'une courte distance, alors que dans une animation de « flux », le changement parcourt en juste la moitié du cycle les granules à grande échelle du blanc au noir, puis en sens inverse. Vous pouvez maintenant combiner l'animation d'ondulations ci-dessus avec une animation de « flux » sous-jacente issue de la même image aléatoire source pour générer une forme bien plus dynamique et fluide, mais attention à cette différence de vitesse d'animation. Par exemple, ici je reprends simplement la précédente Flux Animation créée plus haut et j'y ajoute des ondulations. Dans ce cas, les ondulations ne se déplaceront que parce que le dégradé de l'animation de flux se déplace. |
magick flux_anim.gif -function Sinusoid 3.5,0 flux_rippled_anim.gif
![[IM Output]](../static/img/canvas/flux_rippled_anim.gif)
Vous pouvez aussi animer les ondulations au sein de l'animation. Vous devrez toutefois peut-être utiliser un « taux de cycle de phase » bien plus grand (l'expression « j = 5 * i ») pour les ondulations elles-mêmes. Aussi, comme vous générez un cycle à l'intérieur d'un cycle, vous devrez générer une animation bien plus longue, 60 images dans ce cas. Cela a cependant l'avantage de ralentir aussi les mouvements de « flux » à plus grande échelle. |
for i in `seq 0 10 359`; do
j=`expr $i \* 5`
magick random.png -channel G \
-function Sinusoid 1,${i} \
-virtual-pixel tile -blur 0x8 -auto-level \
-function Sinusoid 2.5,${j} \
-separate +channel miff:-
done |
magick miff:- -set delay 15 -loop 0 ripples_flux_anim.gif
![[IM Output]](../static/img/canvas/ripples_flux_anim.gif)
Notez dans la seconde image comment les ondulations semblent d'abord jaillir d'un point, puis commencer ensuite à y revenir, sans toutefois jamais simplement inverser leur direction. Un meilleur générateur de cycle de flux multi-cyclique devrait supprimer cette légère bizarrerie en éliminant l'effet « négatif » de l'animation de flux sous-jacente.
FUTURE : Utilisation d'images aléatoires ondulées pour des distorsions par carte de dispersion.
Canevas juxtaposés
Les images de tuile peuvent être très grandes ou très petites ; elles sont conçues pour s'emboîter côte à côte et verticalement afin de couvrir de vastes espaces. Grâce au World Wide Web, il y a eu une explosion d'images de tuile disponibles (trouver ce que vous voulez est une autre affaire). Ci-dessous se trouve un ensemble d'images juxtaposées que j'ai copiées depuis la Anthony's Icon Library pour un usage tout au long de ces pages d'exemples. ![[IM Output]](../static/img/images/bg.gif)
bg.gif | ![[IM Output]](../static/img/images/tile_aqua.jpg)
tile_aqua.jpg | ![[IM Output]](../static/img/images/tile_water.jpg)
tile_water.jpg | ![[IM Output]](../static/img/images/rings.jpg)
rings.jpg | ![[IM Output]](../static/img/images/tile_disks.jpg)
tile_disks.jpg | ![[IM Output]](../static/img/images/tile_weave.gif)
tile_weave.gif
---|---|---|---|---|---
Il existe actuellement un assez grand nombre de façons de juxtaposer une image sur une vaste surface. Vous pouvez « [-tile](https://imagemagick.org/command-line-options/#tile) » n'importe quelle image de façon à remplacer complètement l'image de fond d'origine (au moyen de l'opérateur de composition « Copy »). (Pour plus de détails, voir Tile Compositing.) |
magick composite -tile tile_weave.gif -size 60x60 xc:none tile_copy.gif
![[IM Output]](../static/img/canvas/tile_copy.gif)
Une autre façon consiste à lire l'image de tuile à l'aide du codeur « tile: », et à la juxtaposer à une taille précise. |
magick -size 60x60 tile:bg.gif tile_size.gif
![[IM Output]](../static/img/canvas/tile_size.gif)
| _Notez que le codeur « tile: » remplacera toute transparence de l'image par la couleur de fond actuelle. C'est parce qu'en interne, il génère un canevas de la taille demandée et « superpose » l'image de juxtaposition sur ce canevas.
Si vous voulez préserver la transparence, réglez soit « -background none », soit « -compose SRC » (voir Src Compose Method pour les détails)._
---|---
Vous pouvez utiliser ceci pour générer une image juxtaposée bien plus grande que nécessaire, puis utiliser « [-composite](https://imagemagick.org/command-line-options/#composite) » pour la superposer à l'image d'origine. Si l'image de tuile est partiellement transparente, alors une méthode « [-compose](https://imagemagick.org/command-line-options/#compose) » « [Over](compose.html#over) » devra être spécifiée. C'est une méthode de juxtaposition très lente, en particulier pour les grandes images, et vous avez le problème de déterminer quelle taille d'image vous devez créer pour la superposition. |
magick test.png -size 200x200 tile:tile_disks.jpg \
-composite tile_over.gif
![[IM Output]](../static/img/canvas/tile_over.gif)
En spécifiant une tuile comme « motif de remplissage par tuile » pour l'opérateur « [-draw](https://imagemagick.org/command-line-options/#draw) », vous pouvez dessiner l'image de tuile par-dessus une autre image, pour créer n'importe quelle forme ou figure de votre choix. C'est parce que le réglage « [-tile](https://imagemagick.org/command-line-options/#tile) » supplantera tout réglage de couleur « [-fill](https://imagemagick.org/command-line-options/#fill) » utilisé par draw. Voir MVG Drawing Settings. |
magick -size 60x60 xc: -tile tile_aqua.jpg \
-draw "circle 30,30 2,30" tile_draw.gif
![[IM Output]](../static/img/canvas/tile_draw.gif)
Cela ne fonctionne que pour « [-draw](https://imagemagick.org/command-line-options/#draw) » et pour les opérateurs comme « [-annotate](https://imagemagick.org/command-line-options/#annotate) » qui utilisent eux aussi « [-draw](https://imagemagick.org/command-line-options/#draw) » pour accomplir leur fonction. Cela ne fonctionnera pas pour les opérateurs d'image qui utilisent directement la couleur « [-fill](https://imagemagick.org/command-line-options/#fill) », comme « [label:](text.html#label) », « [caption:](text.html#caption) » et « [text:](text.html#text) ». Cependant, « [-draw](https://imagemagick.org/command-line-options/#draw) » intègre des color primitives (primitives de couleur) spéciales, comme la réinitialisation complète de tous les pixels de l'image à la couleur de remplissage ou au motif de tuile (si défini). |
magick test.png -tile tile_water.jpg -draw "color 0,0 reset" \
tile_reset.gif
![[IM Output]](../static/img/canvas/tile_reset.gif)
C'est en réalité exactement la même méthode que celle employée par certaines méthodes de Solid Color Canvases utilisant une Specific Color. Sauf qu'ici, nous avons utilisé « [-tile](https://imagemagick.org/command-line-options/#tile) » au lieu d'une couleur « [-fill](https://imagemagick.org/command-line-options/#fill) ».
Une méthode plus avancée consiste à utiliser un Distort Operator avec un réglage spécial de Distort Viewport, fixé à la taille de l'image d'origine (au moyen d'un Defined Global Artifact et de Percent Escapes). Cela mappe fondamentalement les Virtual Pixels (pixels virtuels) plus petits, qui entourent la petite image de tuile, pour générer le plus grand canevas juxtaposé. |
magick rose: -set option:distort:viewport '%g' +delete \
tree.gif -virtual-pixel tile -filter point -distort SRT 0 \
tile_distort_sized.gif
![[IM Output]](../static/img/canvas/tile_distort_sized.gif)
Voir Tiling via Distort (ci-dessous), où nous examinerons cette même technique pour juxtaposer une image déjà présente en mémoire.
Canevas de juxtaposition décalée
Il faut parfois un peu plus de contrôle sur le positionnement exact d'une texture d'arrière-plan, soit pour aligner un motif de tuiles avec une autre image, soit pour éviter une mauvaise corrélation avec une autre partie de l'image finale. Pour de nombreuses méthodes de pavage standard, cela peut être obtenu à l'aide du réglage "[-tile-offset](https://imagemagick.org/command-line-options/#tile-offset)". Par exemple, ici je fais rouler l'image de tuile utilisée pour créer directement une image de canevas pavée avec "tile:" ou "pattern:".
magick -size 80x80 -tile-offset +30+30 tile:rose: offset_tile.gif
magick -size 80x80 -tile-offset +20+20 \
pattern:checkerboard offset_pattern.gif
| Le réglage Tile Offset était cassé avant la version 6.3.9-9 d'IM, car l'offset 'X' était utilisé à la fois pour les valeurs d'offset 'X' et 'Y' (la valeur 'Y' fournie était ignorée). Cela signifie que si les exemples ci-dessus auraient fonctionné (les offsets X et Y sont identiques), vous risquez de ne pas obtenir les résultats attendus lorsque les deux valeurs diffèrent.
---|---
Cela fonctionne aussi pour le réglage "[-texture](https://imagemagick.org/command-line-options/#texture)" d'arrière-plan de "magick montage". |
montage tree.gif -geometry +24+24 \
-tile-offset +30+30 -texture rose: offset_texture.gif
![[IM Output]](../static/img/canvas/offset_texture.gif)
Vous pouvez aussi utiliser le réglage en le définissant avant le réglage "[-tile](https://imagemagick.org/command-line-options/#tile)" ou "[-fill](https://imagemagick.org/command-line-options/#fill)". Par exemple… |
magick -tile-offset +30+30 -tile rose: \
-size 80x80 xc: -draw 'color 30,20 reset' offset_tile_fill.gif
![[IM Output]](../static/img/canvas/offset_tile_fill.gif)
Assurez-vous que le réglage "[-size](https://imagemagick.org/command-line-options/#size)" est réinitialisé avant de définir l'image "[-tile](https://imagemagick.org/command-line-options/#tile)", mais après que toute autre image a été lue. |
magick -size 80x80 xc: \
-tile-offset +20+20 +size -tile pattern:checkerboard \
-draw 'color 30,20 reset' offset_pattern_good.gif
![[IM Output]](../static/img/canvas/offset_pattern_good.gif)
Quoi qu'il en soit, il vaut probablement mieux définir l'offset de tuile et l'image de tuile juste avant leur première utilisation, ce qui donne le même résultat que la solution ci-dessus.
Paver avec une image déjà en mémoire
Paver une image que vous avez en mémoire (créée ou modifiée) n'est pas simple, et seules quelques méthodes indirectes sont disponibles.
Cloner et concaténer l'image de tuile
Si vous ne vous souciez pas de la taille exacte de l'image pavée, vous pouvez simplement concaténer l'image plusieurs fois. Par exemple, ici nous pavons l'image dans un tableau 3x3. |
magick tree.gif \
\( +clone +clone \) +append \
\( +clone +clone \) -append \
tile_clone.gif
![[IM Output]](../static/img/canvas/tile_clone.gif)
Cette méthode de pavage a l'avantage de vous permettre de paver en miroir (tuiles en miroir) l'image. |
magick tree.gif \
\( +clone -flop +clone \) +append \
\( +clone -flip +clone \) -append \
tile_clone_flip.gif
![[IM Output]](../static/img/canvas/tile_clone_flip.gif)
En général, cette méthode n'est pratique que lorsque vous avez une idée de la taille de l'image à paver. De plus, comme les clones sont en réalité très rapides et efficaces, c'est une méthode de pavage assez simple et rapide, surtout si vous utilisez les résultats pour paver ensuite l'image plus grande.
Paver avec MPR: (Memory Program Register)
Une meilleure méthode consiste à enregistrer l'image dans un format de fichier « en mémoire » spécial "[mpr:](files.html#mpr)", ou 'memory program register'. Depuis ce registre, vous pouvez alors soit utiliser un réglage "[-tile](https://imagemagick.org/command-line-options/#tile)", soit utiliser le lecteur de fichier d'image spécial "tile:", tous deux ne pouvant être définis qu'à partir d'un format de fichier d'image « enregistré ». Par exemple, en utilisant "tile:" pour créer une image pavée d'une taille précise… |
magick tree.gif -write mpr:tile +delete \
-size 100x100 tile:mpr:tile tile_mpr.gif
![[IM Output]](../static/img/canvas/tile_mpr.gif)
| N'oubliez pas que le codeur "tile:" remplacera toute transparence de l'image par la couleur d'arrière-plan actuelle. (voir ci-dessus)
---|---
Ou pavez sur une image existante, en définissant le motif de remplissage "[-tile](https://imagemagick.org/command-line-options/#tile)" ou "[-fill](https://imagemagick.org/command-line-options/#fill)", et en utilisant "[-draw](https://imagemagick.org/command-line-options/#draw)" pour effectuer une réinitialisation de couleur (voir Color Fill Primitives)… |
magick tree.gif -write mpr:tile +delete \
granite: -fill mpr:tile -draw 'color 0,0 reset' \
tile_mpr_reset.gif
![[IM Output]](../static/img/canvas/tile_mpr_reset.gif)
| Si vous pavez avec une image contenant de la transparence, assurez-vous que l'image de destination possède aussi de la transparence en utilisant "-alpha set". Sinon, l'image résultante fera apparaître la couleur de transparence « cachée » des tuiles.
---|---
Ou dessinez avec une autre Draw Primitive, comme un cercle, en utilisant le motif de remplissage. |
magick tree.gif -write mpr:tile +delete \
granite: -tile mpr:tile -draw 'circle 64,64 10,50' \
tile_mpr_fill.gif
![[IM Output]](../static/img/canvas/tile_mpr_fill.gif)
Le nom donné après "[mpr:](files.html#mpr)" peut être ce que vous voulez, ce n'est qu'une étiquette sur le nom de registre 'mpr' utilisé pour stocker l'image (en mémoire). Ce peut même être une étiquette, un nombre, une couleur, ou même un nom de fichier.
Paver avec des pixels virtuels via Distort
Dans cette méthode, nous utilisons le Virtual Pixel Setting pour générer un grand canevas pavé. Ce réglage définit l'aspect que devrait avoir la zone entourant l'image réelle (en dehors des limites normales de l'image). La façon la plus simple d'extraire les pixels virtuels est d'utiliser le Distort Operator avec un réglage Distort Viewport spécial. |
magick tree.gif -set option:distort:viewport 100x100+0+0 \
-virtual-pixel tile -filter point -distort SRT 0 \
tile_distort.gif
![[IM Output]](../static/img/canvas/tile_distort.gif)
Vous avez aussi accès à d'autres styles de réglages de pavage par pixels virtuels, comme '[Mirror](misc.html#mirror)', ou même '[CheckerTile](misc.html#checker_tile)', et même un bon contrôle du pavage décalé grâce au réglage de la fenêtre d'affichage (viewport). |
magick tree.gif -set option:distort:viewport 100x100-10-10 \
-background firebrick -virtual-pixel CheckerTile \
-distort SRT 0 +repage tile_distort_checks.gif
![[IM Output]](../static/img/canvas/tile_distort_checks.gif)
En utilisant le General Distortion Operator de cette manière, vous avez aussi le bonus supplémentaire de déformer l'image pavée de façons très complexes. Vous pouvez en voir des exemples dans Distort Affine Tiling. Comme exemple plus complexe, j'utilise ici une Arc Distortion pour paver le tree autour de l'origine, qui est centrée dans la fenêtre d'affichage. Le '45' spécifie l'angle que couvre la largeur du tree, tandis que le '50' définit le rayon du bord supérieur de la tuile tree. Le reste en découle. |
magick tree.gif -set option:distort:viewport 100x100-50-50 \
-virtual-pixel tile -distort Arc '45 0 50' +repage \
tile_distort_polar.gif
Modifier les motifs/tuiles intégrés d'IM
Voir la liste complète des ImageMagick Built In Images and Patterns. Il existe beaucoup de tels motifs, mais je n'en examinerai qu'un ou deux ici. Or, les motifs intégrés sont généralement de très très petites images, qui peuvent se paver pour couvrir de grandes surfaces. Cependant, seuls, ils ont un aspect très ordinaire et sont plutôt inutiles. Par exemple, voici l'un des motifs plus grands et plus intéressants qui sont fournis… |
magick pattern:checkerboard pattern_default.gif
![[IM Output]](../static/img/canvas/pattern_default.gif)
Les images de motif sont généralement pavées sur de plus grandes surfaces, soit dans le cadre de la création d'un canevas, en réglant un "[-size](https://imagemagick.org/command-line-options/#size)", soit comme tuile de remplissage (voir Tiled Canvases ci-dessus). Sans réglage de taille, la taille de tuile par défaut du motif sera utilisée, soit 30x30 pixels dans ce cas. Vous remarquerez probablement que tous les motifs actuellement fournis par IM sont en noir et blanc purs, à la seule exception du motif 'checkerboard' que j'ai utilisé dans le dernier exemple. Voici un motif que j'aime particulièrement utiliser comme motif de tuile… |
magick -size 60x60 pattern:hexagons pattern_hexagons.gif
![[IM Output]](../static/img/canvas/pattern_hexagons.gif)
Si ces couleurs ne vous conviennent pas, vous pouvez les remplacer à l'aide de l'opérateur d'image "[-opaque](https://imagemagick.org/command-line-options/#opaque)". |
magick -size 60x60 pattern:hexagons \
-fill blue -opaque black -fill skyblue -opaque white \
pattern_colored.gif
![[IM Output]](../static/img/canvas/pattern_colored.gif)
Si vous voulez colorer le motif "checkerboard", le mieux est d'utiliser d'abord "[-auto-level](https://imagemagick.org/command-line-options/#auto-level)" pour mapper les deux gris vers le noir et le blanc avant de substituer ces deux couleurs. Ici, au lieu d'utiliser "[-opaque](https://imagemagick.org/command-line-options/#opaque)" pour remplacer les couleurs, j'utilise un opérateur "[+level-colors](https://imagemagick.org/command-line-options/#level-colors)" (ajouté à IM v6.2.4-1), qui est un peu plus simple à utiliser. |
magick -size 60x60 pattern:checkerboard -auto-level \
+level-colors red,blue pattern_color_checks.gif
![[IM Output]](../static/img/canvas/pattern_color_checks.gif)
Vous pouvez aussi utiliser l'opérateur "[-floodfill](https://imagemagick.org/command-line-options/#floodfill)" pour colorer le motif. Cependant, pour que cela fonctionne correctement, vous devez le faire avant de paver le motif modifié. Dans ce cas, j'ai aussi dû étendre la tuile trois fois pour la colorer avec le motif de couleurs régulier que je voulais. |
magick -size 30x54 pattern:hexagons \
-fill tomato -opaque white \
-fill dodgerblue -draw 'color 10,10 floodfill' \
-fill limegreen -draw 'color 10,25 floodfill' \
-roll +15+27 \
-fill dodgerblue -draw 'color 10,10 floodfill' \
-fill limegreen -draw 'color 10,25 floodfill' miff:- |\
magick -size 100x100 tile:- pattern_color_hexagons.gif
![[IM Output]](../static/img/canvas/pattern_color_hexagons.gif)
J'ai utilisé ci-dessus un pipeline de deux commandes pour séparer la création du motif coloré de son utilisation réelle. Si vous préférez le faire avec une seule commande, voir Tiling an Image In Memory ci-dessus. Vous pouvez aussi gauchir et déformer un simple motif de pavage pour produire des variations intéressantes. Par exemple, un effet de « froissement » (technique empruntée à l'effet IM wrinkle du Font Image Generator) sur un motif d'hexagones m'a paru particulièrement intéressant. |
magick -size 160x100 pattern:hexagons \
-wave 3x100 -background white -rotate 90 -wave 4x66 -rotate -87 \
-gravity center -crop 120x90+0+0 +repage pattern_distorted.gif
Modifier les images de tuile
Le plus gros problème que rencontrent les gens en modifiant des tuiles, qu'il s'agisse d'une tuile existante ou de l'un des motifs intégrés, est que de nombreuses opérations d'image détruisent la « pavabilité » de l'image. Par exemple, ici j'ai pris le motif intégré 'hexagon' et essayé de le modifier pour produire un motif en niveaux de gris ombré de larges lignes hexagonales. |
magick pattern:hexagons -rotate 90 \
-blur 0x1 -edge 1 -negate -shade 120x45 \
miff:- |\
magick -size 100x100 tile:- tile_mod_failure.jpg
![[IM Output]](../static/img/canvas/tile_mod_failure.jpg)
La première commande génère l'« image de tuile » tandis que la seconde pave effectivement l'image, afin que nous puissions voir comment tout s'assemble. Comme vous pouvez le constater, l'image de tuile résultante ne se pave PAS correctement, avec des distorsions de bord artificielles clairement visibles dans l'image pavée. Fondamentalement, nous avons perdu l'uniformité de la tuile d'origine, le long des bords de l'image. Une solution consiste à utiliser un réglage Virtual Pixels spécial, utilisé pour faire croire aux opérateurs que l'image s'enroule autour des bords lorsqu'ils recherchent des couleurs au-delà des limites de l'image réelle proprement dite. |
magick pattern:hexagons -rotate 90 -virtual-pixel tile \
-blur 0x1 -edge 1 -negate -shade 120x45 \
miff:- |\
magick -size 100x100 tile:- tile_mod_vpixels.jpg
![]()
Voici un autre exemple où je joins deux motifs de tuile apparentés, et utilise divers effets pour créer une tuile de mur de briques inhabituelle. |
magick pattern:leftshingle pattern:rightshingle +append \
-virtual-pixel tile -blur 0x0.75 -resize 150% -shade 100x45 \
-fill Peru -tint 100% miff:- |\
magick -size 100x100 tile:- tile_slanted_bricks.jpg
Alternative
Il existe une alternative au recours aux Virtual Pixels. En gros, nous fournissons nous-mêmes les « pixels de bord virtuels » avant d'opérer sur l'image, afin d'éviter tout effet de bord susceptible d'être présent. Et cela se fait en pavant d'abord l'image sur une surface légèrement plus grande. Après avoir modifié l'image, nous pouvons ré-extraire la tuile, en évitant les distorsions de bord qui ont été introduites. Il n'est pas nécessaire qu'elle soit beaucoup plus grande, selon l'ampleur des opérations d'image effectuées. J'ai constaté que 15 à 40 pixels devraient arrêter tous les effets de bord dans le résultat final. Pour ré-extraire l'image, nous pouvons soit rogner les pixels supplémentaires avec "[-shave](https://imagemagick.org/command-line-options/#shave)", soit rogner la taille de tuile d'origine au milieu de l'image traitée avec "[-crop](https://imagemagick.org/command-line-options/#crop)". Par exemple, ici je crée un effet "[-shade](https://imagemagick.org/command-line-options/#shade)" 3D en utilisant le motif intégré 'hexagons'. |
magick -size 60x60 tile:pattern:hexagons -rotate 90 \
-blur 0x1 -edge 1 -negate -shade 120x45 \
-gravity center -crop 18x30+0+0 +repage miff:- |\
magick -size 100x100 tile:- tile_mod_success.jpg
![[IM Output]](../static/img/canvas/tile_mod_success.jpg)
Notez que la position exacte de la tuile extraite n'a pas d'importance. Une image pavable peut être découpée n'importe où dans l'image pavée, du moment qu'elle est éloignée des bords déformés et que vous utilisez la même taille d'origine de la tuile. Ici, au lieu de paver l'image sur une plus grande surface, nous utilisons une technique de « double clone » pour doubler la surface que la tuile couvre. Une fois terminé, il ne reste plus qu'à découper au centre 50 % de l'image pour récupérer notre tuile modifiée. Cela signifie que nous n'avons pas besoin de connaître la taille exacte de la tuile que vous traitez. |
magick pattern:circles \( +clone \) +append \( +clone \) -append \
-fill grey -opaque black -blur 0x0.5 -shade 120x45 \
-gravity center -crop 50% +repage miff:- |\
magick -size 100x100 tile:- tile_circles.jpg
![[IM Output]](../static/img/canvas/tile_circles.jpg)
Générer des images de tuile. Le plus gros problème que vous rencontrez en générant des images qui peuvent se paver ensemble est d'essayer de faire correspondre les bords et les coins de l'image afin qu'ils s'emboîtent sans coutures. Si cela n'est pas fait, tout ce que vous obtenez est un ensemble de boîtes carrées, chacune contenant une copie répétée de l'image. Ce n'est pas une affaire facile et cela peut être une expérience très frustrante et à s'arracher les cheveux. Un objet apparaissant dans la tuile sur un bord doit réapparaître de l'autre côté de l'image afin de reformer l'ensemble lorsque l'image est pavée. Si vous pouvez le faire assez facilement avec des images générées par ordinateur, il est quasiment impossible de produire une bonne image de pavage présentant des photographies du monde réel. L'autre problème majeur est d'essayer de faire en sorte que la tuile ne semble pas se répéter. La seule vraie solution à cela est de rendre vos images de tuile assez grandes pour contenir suffisamment d'éléments très similaires, mais tout de même différents, pour qu'il devienne difficile de voir un motif répété. Pour cette raison, générer de petites tuiles qui ne semblent pas se répéter est particulièrement difficile.
FUTURE: Des idées et suggestions pour générer des motifs de tuile ? Quelqu'un ?
Ou rouler, ajouter un élément, rouler, ajouter un élément, etc…
Toutes les suggestions et tous les exemples sont acceptés.
Suggestions pour générer une tuile à partir de vraies photos de motifs répétitifs,
tels que l'eau, les feuilles mortes, les nuages, le stuc, la maçonnerie, etc…
Générer des motifs de tuile à la manière d'Escher.
Tuile de bruit aléatoire
Parce qu'un canevas de bruit aléatoire brut n'a au départ aucune caractéristique de bord (la couleur de chaque pixel est totalement indépendante de celle de tous ses voisins), vous pouvez le paver sans vous soucier des distorsions de bord. En gros, c'est tellement extrêmement aléatoire au niveau du pixel qu'aucun bord ne correspond au départ, donc nous ne perdons rien en pavant. Malheureusement, très peu de situations utiliseraient une image de bruit aléatoire brut, telle quelle, dans un but réel. Elle est tout simplement si horriblement aléatoire qu'elle est inutile. Cependant, en modifiant l'image tout en préservant sa pavabilité inhérente, nous pouvons créer à peu près n'importe quel motif de tuile aléatoire que nous voulons. Par exemple, examinons un simple "[-blur](https://imagemagick.org/command-line-options/#blur)" de la tuile d'origine, en utilisant la même technique de « modification d'une tuile » que nous avons utilisée dans le dernier exemple. |
magick -size 64x64 xc: +noise Random \
-virtual-pixel tile -blur 0x6 -auto-level tile_random.jpg
magick -size 128x128 tile:tile_random.jpg tiled_random.jpg
![[IM Output]](../static/img/canvas/tile_random.jpg)
![[IM Output]](../static/img/canvas/tiled_random.jpg)
Grâce à cette technique, vous pouvez appliquer à peu près n'importe quelle transformation à une image de bruit aléatoire brut. Par exemple… |
magick -size 64x64 xc: +noise Random \
-virtual-pixel tile -blur 0x6 -edge 1 -fx G \
-shade 280x45 -auto-level tile_random_pits.jpg
magick -size 128x128 tile:tile_random_pits.jpg tiled_random_pits.jpg
![[IM Output]](../static/img/canvas/tile_random_pits.jpg)
![[IM Output]](../static/img/canvas/tiled_random_pits.jpg)
Comme vous pouvez le voir, il est bien plus simple de créer des tuiles aléatoires en utilisant l'image de bruit aléatoire brut, et vous n'aurez aucune distorsion de bord dans les résultats. Cette transformation d'image particulière est répertoriée sur la page Background Images et s'intitule « pits ». Consultez cette page pour de nombreuses autres transformations d'image aléatoires, et des exemples de leur apparence.
Pavage hexagonal
Plutôt que de paver de façon carrée, l'image de « bruit aléatoire » permet de générer un type de tuile très différent. En doublant les dimensions de l'image et en reposant la tuile dans l'espace supplémentaire, mais décalée de moitié, nous pouvons générer un motif de tuile hexagonal de bruit aléatoire de base. C'est le même type d'effet de pavage que celui obtenu en pavant le motif intégré spécial "pattern:hexagons" d'ImageMagick. |
magick pattern:hexagons tile_hexagons.gif
magick -size 64x64 pattern:hexagons tiled_hexagons.gif
![[IM Output]](../static/img/canvas/tile_hexagons.gif)
![[IM Output]](../static/img/canvas/tiled_hexagons.gif)
Notez cependant que, pour que cette tuile ait l'air « hexagonale », la tuile ne peut pas être un carré normal, ni même un carré doublé. La taille finale de la tuile doit être un rectangle. Le rapport exact de ce rectangle fait en réalité intervenir des nombres irrationnels, ce qui n'est pas très bon pour un travail d'image avec un tableau de pixels. Cependant, un bon rapport pratique est 4:3, qui est utilisé par la plupart des images d'ordinateur et d'appareil photo numérique. Ici, nous superposons deux fois de plus la même image de « bruit aléatoire » (un rectangle au rapport 2:3) pour générer le motif hexagonal de base (dans un rectangle 4:3). La tuile de bruit aléatoire pavée en hexagones est ensuite transformée à l'aide de la transformation « paint_3s » de la page Background Images, pour générer un motif de tuile hexagonal d'assez bel aspect. |
magick -size 48x64 xc: +noise Random -write mpr:rand \
-extent 96x64 -page +48-32 mpr:rand -page +48+32 mpr:rand \
-flatten tile_hex_random.jpg
magick tile_hex_random.jpg -virtual-pixel tile -blur 0x10 -paint 3 \
-shade 280x45 -auto-level tile_hex_layered.jpg
magick -size 160x160 tile:tile_hex_layered.jpg tiled_hex_layered.jpg
![[IM Output]](../static/img/canvas/tile_hex_layered.jpg)
![[IM Output]](../static/img/canvas/tiled_hex_layered.jpg)
Si vous regardez le motif que produit la tuile, vous verrez que toute caractéristique spécifique aura 6 copies de cette même caractéristique l'entourant en cercle. C'est le motif « hexagonal » que produit la tuile, même si elle est toujours pavée selon le même motif « carré » que toutes les autres images de pavage. Une variante du motif « hextile » ci-dessus consiste à doubler l'image de tuile verticalement, plutôt qu'horizontalement comme nous l'avons fait ci-dessus. Le résultat est que le motif hexagonal sera pivoté de quatre-vingt-dix degrés. Il s'agit toutefois toujours du même type de motif. | _Mathématiquement, ce qui précède ne génère pas un nouveau Wallpaper Group (groupe de papier peint) à partir d'une tuile existante. L'image « non hexagonale » d'origine et la version finale appartiennent toutes deux au même groupe de pavage 'p1 '.
Ce que nous faisons réellement ci-dessus, c'est convertir un motif de pavage à « prototuile » en losange en un « domaine fondamental » rectangulaire plus grand, aligné orthogonalement, du même motif de pavage. De cette façon, vous pouvez ensuite paver l'image à l'aide d'une méthode de pavage standard.
---|---
_Future: retourner l'image supplémentaire pour générer un motif de pavage plus grand (groupe de pavage pmg). Future: comment découper (masquer) un hexagone d'une image afin qu'elle se pave parfaitement, sans espaces ni chevauchements.
Pavage hexagonal triple
Comme nous l'avons fait en colorant le motif intégré "hexagons" (voir Modifying Built-in IM Patterns/Tiles ci-dessus), vous pouvez créer trois variantes différentes de la tuile initiale (avec des rotations par exemple) avant de les remapper pour former la tuile plus grande. Bien sûr, tout comme lorsque j'ai coloré le motif "hexagons", l'image de tuile finale devra être agrandie trois fois pour générer un motif de tuile rectangulaire répétitif. Les variations entre les trois tuiles générées ne doivent pas être trop différentes, et devraient survivre à tout post-traitement, sinon vous n'obtiendrez pas les avantages de la technique. Cela signifie que la tuile initiale doit être elle aussi raisonnablement grande, afin que toute caractéristique distincte présente soit préservée. Par exemple, ici nous prenons un dessin au trait très simple, et le pivotons pour produire 3 variations similaires. Ces images pivotées sont ensuite pavées sept fois sur un plus grand canevas (6 fois plus grand) pour produire le motif hexagonal à triple image. |
magick -size 24x24 xc: -draw "rectangle 3,11 20,12" tile_line.gif
magick tile_line.gif -gravity center \
\( +clone -rotate 0 -crop 24x18+0+0 -write mpr:r1 +delete \) \
\( +clone -rotate 120 -crop 24x18+0+0 -write mpr:r2 +delete \) \
-rotate -120 -crop 24x18+0+0 -write mpr:r3 +repage \
-extent 72x36 \( -page +0+0 mpr:r3 \) \
\( -page +24+0 mpr:r1 \) \( -page +48+0 mpr:r2 \) \
\( -page -12+18 mpr:r1 \) \( -page +12+18 mpr:r2 \) \
\( -page +36+18 mpr:r3 \) \( -page +60+18 mpr:r1 \) \
-flatten tile_hex_lines.jpg
magick -size 120x120 tile:tile_hex_lines.jpg tiled_hex_lines.jpg
![[IM Output]](../static/img/canvas/tile_line.gif)
![[IM Output]](../static/img/canvas/tile_hex_lines.jpg)
![[IM Output]](../static/img/canvas/tiled_hex_lines.jpg)
Cependant, ce qui précède ne fonctionne que pour paver une petite forme au milieu de l'image d'origine. Cela ne fonctionne pas bien pour une image générale. Pour le pavage hexagonal d'une image générale, nous devons aussi masquer des triangles équilatéraux. Les pièces sont ensuite pivotées de sorte que les bords des triangles équilatéraux soient en miroir. Ce n'est pas une tâche facile.
Pavage à miroir diagonal
Voici une façon de prendre n'importe quelle image carrée et de la transformer en 8 images en miroir autour d'un point central. Plus précisément, nous générons un motif de pavage 'p4m ' complexe. Je génère d'abord une Random Hue Image, et en utilisant la moitié inférieure gauche de l'image source, je la mets en miroir diagonalement, puis horizontalement et verticalement. |
magick -size 50x50 xc: +noise Random -virtual-pixel Tile -blur 0x5 \
-auto-level -separate -background white \
-compose ModulusAdd -flatten -channel R -combine +channel \
-set colorspace HSB -colorspace RGB tile_diag_source.jpg
magick tile_diag_source.jpg \( +clone -transpose \) \
\( +clone -sparse-color voronoi '%w,0 white 0,%h black' \) \
-composite \
\( +clone -flop -chop 1x0 \) +append \
\( +clone -flip -chop 0x1 \) -append \
tile_diag_mirror.jpg
![[IM Output]](../static/img/canvas/tile_diag_source.jpg)
![[IM Output]](../static/img/canvas/tile_diag_mirror.jpg)
Le miroir diagonal est généré en effectuant un Transpose puis en utilisant un masque généré à l'aide d'un Voronoi, Sparse Color. Notez que ce miroir diagonal partage automatiquement une ligne de pixels de part et d'autre du miroir de la même façon, du fait de la géométrie en pixels du carré. Je retire aussi un ensemble de pixels le long du bord avant de créer les Flips and Flops verticaux et horizontaux. Je recommande aussi de retirer une autre rangée et une autre colonne de pixels le long des bords supérieur et gauche, avant d'utiliser cette image comme « tuile ». Vous n'êtes pas obligé de le faire, mais je trouve que c'est plus joli. Sans retirer une rangée et une colonne de pixels de bord, vous obtenez de vilaines « coutures » de pixels doublés, là où les images se rejoignent. Une alternative consiste à paver d'abord l'image aléatoire brute, puis à effectuer la conversion Background Pattern ; vous risquez moins d'obtenir un « aspect rogné » le long des lignes de miroir, mais une transition plus douce. |
magick -size 51x51 xc: +noise Random \( +clone -transpose \) \
\( +clone -sparse-color voronoi '%w,0 white 0,%h black' \) \
-composite \
\( +clone -flop -chop 1x0 \) +append \
\( +clone -flip -chop 0x1 \) -append \
-chop 1x1 \
\
-virtual-pixel Tile -blur 0x5 -auto-level \
-separate -background white \
-compose ModulusAdd -flatten -channel R -combine +channel \
-set colorspace HSB -colorspace RGB tile_p4m.jpg
![[IM Output]](../static/img/canvas/tile_p4m.jpg)
La première partie est la génération du « pavage des données aléatoires », la seconde moitié où je transforme les données aléatoires en un mappage de « teintes ». J'ai aussi ajouté le pixel supplémentaire à l'image initiale, qui sera plus tard découpé comme il convient pour générer une image pavable.
Pour une introduction plus complète aux images pavables et aux mathématiques qui les sous-tendent, voir Wikipedia: Wallpaper Group. Ce que nous avons exploré ci-dessus n'est qu'une petite partie des nombreux motifs de pavage que vous pouvez créer.
Le 'p4g ' est presque exactement identique au pavage 'p4m ' ci-dessus, mais utilise des rotations de 180 degrés des carrés en miroir, plutôt que des flips, pour générer l'image de pavage complète. Cependant, comme les images ne sont pas jointes par des miroirs, vous ne pouvez pas utiliser une image existante comme source de tuile, car les bords deviendront disjoints et discontinus. Vous pouvez toutefois paver les données aléatoires brutes puis traiter l'image de tuile résultante, pour produire un résultat lisse. |
magick -size 50x50 xc: +noise Random \( +clone -transpose \) \
\( +clone -sparse-color voronoi '%w,0 white 0,%h black' \) \
-composite \
\( +clone -rotate -90 \) +append \
\( +clone -rotate 180 \) -append \
\
-virtual-pixel Tile -blur 0x5 -auto-level \
-separate -background white \
-compose ModulusAdd -flatten -channel R -combine +channel \
-set colorspace HSB -colorspace RGB tile_p4g.jpg
![[IM Output]](../static/img/canvas/tile_p4g.jpg)
Notez qu'en raison de la nature non miroir du pavage, vous n'avez pas besoin de retirer la rangée ou la colonne de pixels dupliqués des bords avant de concaténer. Cela dit, il n'est pas nuisible de le faire, si vous voulez suivre le même type de processus dans les deux cas.
![[IM Output]](../static/img/canvas/canvas_rose_red.gif)
![[IM Output]](../static/img/images/test.png)
![[IM Output]](../static/img/canvas/color_pick_draw.png)
![[IM Output]](../static/img/canvas/color_pick_distort.png)
![[IM Output]](../static/img/canvas/black_threshold.png)
![[IM Output]](../static/img/canvas/black_level.png)
![[IM Output]](../static/img/canvas/black_fx.png)
![[IM Output]](../static/img/canvas/black_evaluate.png)
![[IM Output]](../static/img/canvas/black_gamma.png)
![[IM Output]](../static/img/canvas/black_alpha.png)
![[IM Output]](../static/img/canvas/white_threshold.png)
![[IM Output]](../static/img/canvas/white_level.png)
![[IM Output]](../static/img/canvas/white_fx.png)
![[IM Output]](../static/img/canvas/white_evaluate.png)
![[IM Output]](../static/img/canvas/white_alpha.png)
![[IM Output]](../static/img/canvas/trans_compose.png)
![[IM Output]](../static/img/canvas/color_matte.png)
![[IM Output]](../static/img/canvas/trans_fx.png)
![[IM Output]](../static/img/canvas/trans_evaluate.png)
![[IM Output]](../static/img/canvas/trans_threshold.png)
![[IM Output]](../static/img/canvas/grey_level.png)
![[IM Output]](../static/img/canvas/gradient_range1.jpg)
![[IM Output]](../static/img/canvas/gradient_range2.jpg)
![[IM Output]](../static/img/canvas/gradient_range3.jpg)
![[IM Output]](../static/img/canvas/gradient_range4.jpg)
![[IM Output]](../static/img/canvas/gradient_range5.jpg)
![[IM Output]](../static/img/canvas/rgradient_range1.jpg)
![[IM Output]](../static/img/canvas/rgradient_range2.jpg)
![[IM Output]](../static/img/canvas/rgradient_range3.jpg)
![[IM Output]](../static/img/canvas/rgradient_range4.jpg)
![[IM Output]](../static/img/canvas/rgradient_range5.jpg)
![[IM Output]](../static/img/canvas/gradient_trans_colorize.png)
![[IM Output]](../static/img/canvas/gradient_arc.jpg)
![[IM Output]](../static/img/canvas/gradient_bird.jpg)
![[IM Output]](../static/img/canvas/gradient_colormap.jpg)
![[IM Output]](../static/img/canvas/gradient_rainbow.jpg)
![[IM Output]](../static/img/canvas/gradient_rainbow_2.jpg)
![[IM Output]](../static/img/canvas/gradient_rs_rainbow.jpg)
![[IM Output]](../static/img/canvas/gradient_interpolated.jpg)
![[IM Output]](../static/img/canvas/gradient_clut_recolored.jpg)
![[IM Output]](../static/img/canvas/gradient_clut.jpg)
![[IM Output]](../static/img/canvas/gradient_fx_x4.gif)
![[IM Output]](../static/img/canvas/gradient_inverse_alt.gif)
![[IM Output]](../static/img/canvas/gradient_shepards_alt.gif)
![[IM Output]](../static/img/canvas/gradient_inverse_RGB.png)
![[IM Output]](../static/img/canvas/gradient_inverse_RGB_Hue.gif)
![[IM Output]](../static/img/canvas/sparse_bary_triangle.png)
![[IM Output]](../static/img/canvas/sparse_bary_0.gif)
![[IM Output]](../static/img/canvas/sparse_bary_1.gif)
![[IM Output]](../static/img/canvas/sparse_bary_2.gif)
![[IM Output]](../static/img/canvas/sparse_bary_gradient_2.png)
![[IM Output]](../static/img/canvas/diagonal_gradient.jpg)
![[IM Output]](../static/img/canvas/diagonal_gradient_2.jpg)
![[IM Output]](../static/img/canvas/sparse_bary_two_point_wide.jpg)
![[IM Output]](../static/img/canvas/sparse_bilin_0.gif)
![[IM Output]](../static/img/canvas/sparse_bilin_1.gif)
![[IM Output]](../static/img/canvas/sparse_bilin_2.gif)
![[IM Output]](../static/img/canvas/sparse_inverse_near.png)
![[IM Output]](../static/img/canvas/sparse_inverse_far.png)
![[IM Output]](../static/img/images/figure.gif)
![[IM Output]](../static/img/canvas/shape_edge_in_lights.png)
![[IM Output]](../static/img/canvas/shape_in_lights.png)
![[IM Output]](../static/img/canvas/sparse_blur_simple.png)
![[IM Output]](../static/img/canvas/sparse_blur_layered.png)
![[IM Output]](../static/img/canvas/sparse_lines_near_source.gif)
![[IM Output]](../static/img/canvas/plasma1.jpg)
![[IM Output]](../static/img/canvas/plasma2.jpg)
![[IM Output]](../static/img/canvas/plasma3.jpg)
![[IM Output]](../static/img/canvas/plasma_range1.jpg)
![[IM Output]](../static/img/canvas/plasma_range2.jpg)
![[IM Output]](../static/img/canvas/plasma_range3.jpg)
![[IM Output]](../static/img/canvas/plasma_range4.jpg)
![[IM Output]](../static/img/canvas/plasma_range5.jpg)
![[IM Output]](../static/img/canvas/plasma_black.jpg)
![[IM Output]](../static/img/canvas/plasma_grey.jpg)
![[IM Output]](../static/img/canvas/plasma_white.jpg)
![[IM Output]](../static/img/canvas/plasma_yellow.jpg)
![[IM Output]](../static/img/canvas/plasma_tomato.jpg)
![[IM Output]](../static/img/canvas/plasma_steelblue.jpg)
![[IM Output]](../static/img/canvas/plasma_fractal1.jpg)
![[IM Output]](../static/img/canvas/plasma_fractal2.jpg)
![[IM Output]](../static/img/canvas/plasma_fractal3.jpg)
![[IM Output]](../static/img/canvas/plasma_swirl.jpg)
![[IM Output]](../static/img/canvas/plasma_grey0.jpg)
![[IM Output]](../static/img/canvas/plasma_grey1.jpg)
![[IM Output]](../static/img/canvas/plasma_grey2.jpg)
![[IM Output]](../static/img/canvas/plasma_grey3.jpg)
![[IM Output]](../static/img/canvas/plasma_grey4.jpg)
![[IM Output]](../static/img/canvas/plasma_grey5.jpg)
![[IM Output]](../static/img/canvas/plasma_grey6.jpg)
![[IM Output]](../static/img/canvas/plasma_grey7.jpg)
![[IM Output]](../static/img/canvas/plasma_grey8.jpg)
![[IM Output]](../static/img/canvas/plasma_grey9.jpg)
![[IM Output]](../static/img/canvas/plasma_rnd1.jpg)
![[IM Output]](../static/img/canvas/plasma_rnd2.jpg)
![[IM Output]](../static/img/canvas/plasma_rnd3.jpg)
![[IM Output]](../static/img/canvas/plasma_rnd4.jpg)
![[IM Output]](../static/img/canvas/plasma_rnd5.jpg)
![[IM Output]](../static/img/canvas/plasma_high_aspect.jpg)
![[IM Output]](../static/img/canvas/plasma_flaw.jpg)
![[IM Output]](../static/img/canvas/random_black.png)
![[IM Output]](../static/img/canvas/random_white.png)
![[IM Output]](../static/img/canvas/random_trans.png)
![[IM Output]](../static/img/canvas/random_1.png)
![[IM Output]](../static/img/canvas/random_3.png)
![[IM Output]](../static/img/canvas/random_5.png)
![[IM Output]](../static/img/canvas/random_10.png)
![[IM Output]](../static/img/canvas/random_20.png)
![[IM Output]](../static/img/canvas/random_0_gray.png)
![[IM Output]](../static/img/canvas/random_1_gray.png)
![[IM Output]](../static/img/canvas/random_3_gray.png)
![[IM Output]](../static/img/canvas/random_10_gray.png)
![[IM Output]](../static/img/canvas/random_20_gray.png)
![[IM Output]](../static/img/canvas/random_0_thres.png)
![[IM Output]](../static/img/canvas/random_1_thres.png)
![[IM Output]](../static/img/canvas/random_3_thres.png)
![[IM Output]](../static/img/canvas/random_5_thres.png)
![[IM Output]](../static/img/canvas/random_10_thres.png)
![[IM Output]](../static/img/canvas/random_20_thres.png)
![[IM Output]](../static/img/canvas/flux_0.png)
![[IM Output]](../static/img/canvas/flux_30.png)
![[IM Output]](../static/img/canvas/flux_60.png)
![[IM Output]](../static/img/canvas/flux_90.png)
![[IM Output]](../static/img/canvas/flux_120.png)
![[IM Output]](../static/img/canvas/flux_150.png)
![[IM Output]](../static/img/canvas/flux_330.png)
![[IM Output]](../static/img/canvas/flux_300.png)
![[IM Output]](../static/img/canvas/flux_270.png)
![[IM Output]](../static/img/canvas/flux_240.png)
![[IM Output]](../static/img/canvas/flux_210.png)
![[IM Output]](../static/img/canvas/flux_180.png)
![[IM Output]](../static/img/canvas/ripples_1.png)
![[IM Output]](../static/img/canvas/ripples_2.png)
![[IM Output]](../static/img/canvas/ripples_3.png)
![[IM Output]](../static/img/canvas/ripples_4.png)
![[IM Output]](../static/img/canvas/random_enhanced.png)
![[IM Output]](../static/img/canvas/ripples_4e.png)
![[IM Output]](../static/img/canvas/random_sigmoidal.png)
![[IM Output]](../static/img/canvas/ripples_4s.png)
![[IM Output]](../static/img/canvas/ripples_3e000.png)
![[IM Output]](../static/img/canvas/ripples_3e090.png)
![[IM Output]](../static/img/canvas/ripples_3e180.png)
![[IM Output]](../static/img/canvas/ripples_3e270.png)
![[IM Output]](../static/img/canvas/offset_tile.gif)
![[IM Output]](../static/img/canvas/offset_pattern.gif)
![[IM Output]](../static/img/canvas/tile_distort_polar.gif)
![[IM Output]](../static/img/canvas/pattern_distorted.gif)
![[IM Output]](../static/img/canvas/tile_slanted_bricks.jpg)