Manipulation des effets visuels avec ColorMatrixFilter et ConvolutionFilter

ColorMatrixFilter et ConvolutionFilter peuvent être utilisés pour transformer visuellement vos objets Flash. Dans cet article, je vais vous montrer à quel point ils sont faciles à manipuler, en utilisant un outil pratique que j'ai construit pour une expérimentation simple..




introduction

Avez-vous déjà expérimenté les filtres ColorMatrix et Convolution de Flash? Je cherchais quelque chose d'intéressant que vous puissiez faire avec Flash et je les ai rencontrés. Les expérimenter peut donner des résultats impressionnants.

J'ai écrit un testeur pour le rendre facile à expérimenter. Découvrez ces photos que j'ai prises en jouant avec:

Maintenant, si vous trouvez cela intéressant, laissez-moi vous expliquer en quoi consistent ces deux filtres..

Le filtre matriciel couleur

Le filtre matriciel couleur est utilisé pour manipuler la couleur d'un objet d'affichage.

Laissez-moi vous expliquer le calcul exact effectué par ColorMatrixFilter. Chaque pixel d'une image est un mélange de rouge, de vert et de bleu. Celles-ci couleurs primaires, quand ils sont combinés, peuvent faire n'importe quelle autre couleur:

Image de Wikimedia Commons. Merci à Mike Horvath et à Jacobolus.

La quantité de rouge dans un pixel peut varier de zéro (pas de rouge du tout) à 255. Même chose pour le vert et le bleu. Ainsi, à partir de l'image ci-dessus, vous pouvez voir qu'un pixel jaune pur a le rouge = 255 et le vert = 255. Le blanc a le rouge, le vert et le bleu tous réglés sur 255. Le noir les met tous les trois à zéro..

Le filtre de matrice de couleurs examine chaque pixel d'une image source et les modifie en fonction de la quantité de rouge, de bleu et de vert dans le pixel. Vous vous retrouvez avec une toute nouvelle image; la image de destination.

Voici comment ça fonctionne

Tout d’abord, concentrons-nous sur ces trois valeurs:

Étiquetons ces valeurs a [0], a [1] et a [2] à leur tour. Maintenant, pensez à un seul pixel dans l’ensemble de l’image source (celui dans le coin supérieur gauche fera l'affaire). Appelons la quantité de rouge dans cette srcR, la quantité de vert srcG et la quantité de bleu srcB.

La question est: combien de rouge sera dans ce pixel de l'image de destination, destR? Flash utilise ce calcul:

 destR = (a [0] * srcR) + (a [1] * srcG) + (a [2] * srcB);

Ici vous pouvez voir qu'un [0] est 1, alors qu'un [1] et un [2] sont tous deux nuls, donc:

 destR = (1 * srcR) + (0 * srcG) + (0 * srcB); // ce qui signifie… destR = srcR;

Il n'y a pas de changement! Mais que se passe-t-il si nous changeons un [0] à zéro et un [1] à 1? Ensuite:

 destR = (0 * srcR) + (1 * srcG) + (0 * srcB); // ce qui signifie… destR = srcG;

… La quantité de rouge dans le pixel de destination serait égale à la quantité de vert dans le pixel source! En outre, si vous avez modifié la deuxième ligne pour lire "1 0 0", alors la quantité de vert dans le pixel de destination serait égale à la quantité de rouge dans le pixel source; vous les auriez permutés et votre poisson orange deviendrait un poisson vert:

Vous vous demandez probablement à propos de la UNE colonne et ligne et à propos de la Décalage colonne. Eh bien, A signifie alpha, ce qui signifie transparence. Les valeurs A ont sensiblement le même effet que les valeurs R G B, mais comme aucune de ces images exemple n'est transparente, il est difficile à démontrer. La colonne Décalage vous permet simplement d’augmenter ou de diminuer la quantité de rouge, de bleu ou de vert dans le pixel de destination: tapez -255 dans la colonne Décalage de la ligne R et vous verrez qu’il n’ya plus de rouge dans l’image..

Expérience

Je me rends compte qu’il est difficile de comprendre cela simplement en lisant à ce sujet. Nous allons donc examiner quelques exemples d’effets intéressants. C'est beaucoup plus amusant, de toute façon. Mais d’abord, pour les plus curieux, voici la formule mathématique utilisée par Flash:

 destR = (a [0] * srcR) + (a [1] * srcG) + (a [2] * srcB) + (a [3] * srcA) + a [4]; destG = (a [5] * srcR) + (a [6] * srcG) + (a [7] * srcB) + (a [8] * srcA) + a [9]; destB = (a [10] * srcR) + (a [11] * srcG) + (a [12] * srcB) + (a [13] * srcA) + a [14]; destA = (a [15] * srcR) + (a [16] * srcG) + (a [17] * srcB) + (a [18] * srcA) + a [19];

(Chacune des valeurs que vous voyez dans la matrice 5x4 peut varier entre -255 et 255.)

Jetez un coup d'œil à l'exemple d'image "Nuancier":

Supposons maintenant que vous souhaitiez supprimer toutes les couleurs rouges de l’image. Définissez simplement toutes les valeurs de la ligne R à zéro:

Ça signifie:

 destR = (0 * srcR) + (0 * srcG) + (0 * srcB) + (0 * srcA) + 0; // ce qui signifie: destR = 0 + 0 + 0 + 0 + 0 + 0; // so: destR = 0;

Maintenant, supposons que vous souhaitiez ajouter un peu plus de vert là où il y en avait auparavant. Mettez "1" à l'entrée 0x1, ainsi la ligne G lit "1 1 0 0 0":

Réalisons maintenant quelque chose de très étrange en modifiant la ligne G en "0 -1 0 0 50":

Qu'est-ce qui vient juste de se passer? Par exemple, si à un pixel quelconque vous avez vert = 30, il est multiplié par «-1» et ensuite 50 est ajouté, le résultat est donc: (30 * -1) + 50 = 20.

Par conséquent, un type de seuil est créé: pour chaque pixel ayant une valeur verte supérieure à 50, son pixel transformé sera complètement désactivé. Pourquoi? Eh bien, supposons que le canal vert du pixel ait une valeur de 51:

 destG = (0 * srcR) + (-1 * srcG) + (0 * srcB) + (0 * srcA) + 50; // souviens-toi srcG = 51: destG = 0 + (-51) + 0 + 0 + 50; // so: destG = - 51 + 50; // so: destG = -1; // mais un pixel ne peut pas avoir une quantité négative de vert, c'est donc mis à zéro: destG = 0;

Maintenant, essayez ceci:

Tous les pixels avec des valeurs vertes supérieures à 50 sont désactivés et ceux dont les valeurs vertes sont inférieures à 50 ont les trois canaux de couleur augmentés. Cela vous permet de voir les zones de l’image qui n’ont que très peu de vert, comme dans l’image de poisson:

X

Ici, seuls les pixels avec une quantité de vert inférieure à 50. Plus le pixel est sombre, plus il y a de vert dans l'image d'origine. C'est le principe de base de toute façon. Je sais que cela peut sembler compliqué au début, mais jouez avec et vous l'obtiendrez finalement :)

Niveaux de gris

OK, passons à quelque chose de standard: une image en niveaux de gris. Changez votre matrice comme suit:

Vous avez une échelle de gris. Agréable :)

Couleurs Inversées

Réalisons un autre état de couleur populaire: Couleurs inversées.

Pour inverser les couleurs, nous devons faire en sorte que chaque pixel avec une valeur rouge de 255 ait une valeur rouge de zéro et vice-versa. Même chose pour les deux autres couleurs. Nous devons donc créer un code d’exécution Flash ressemblant à ceci:

 destR = 255 - srcR; destG = 255 - srcG; destB = 255 - srcB;

Mais c'est facile! Tout ce que nous avons à faire est de définir la matrice comme ceci:

Tada! Poisson électrique:

Plus d'effets

La plupart des effets les plus exotiques que permet le ColorMatrixFilter sont obtenus en définissant une valeur négative pour une couleur et une valeur positive pour un décalage - ou inversement. Mettez "-1" de 0x3 à 2x3 (les alphas) ​​et 255 pour le décalage de l'alpha (4x3).
Wow, maintenant je sais maintenant comment ils ont fait Terminator 2 :)

Honnêtement, je ne suis pas vraiment sûr de ce que je viens de faire - les calculs deviennent vraiment difficiles à suivre après un certain temps.

Bien qu'il soit possible de comprendre le fonctionnement du ColorMatrixFilter d'un point de vue mathématique, il restera réaliste de vouloir jouer avec. Vous ne pouvez jamais savoir exactement ce qui va apparaître lorsque vous définissez des valeurs spécifiques. C'est pourquoi j'ai créé ce EffectsTester. Alors jouez. Faites-vous vert métallique, ou rouge, ou incolore.

Application dans le monde réel

Lorsque vous avez un effet que vous aimez, vous pouvez l'appliquer à n'importe quel objet DisplayObject (MovieClip, Sprite, Bitmap…) dans votre propre code, comme ceci:

 // importez d'abord ColorMatrixFilter en haut de votre code: import flash.filters.ColorMatrixFilter; //… plus tard: filtres var: Array = new Array (); // pour tout ce qui suit "= new", copiez et collez-le dans la zone "Saisir le code" de EffectsTester: var cmf: ColorMatrixFilter = new ColorMatrixFilter (new Array (-1,0,0,0,255,0, -1,0 , 0,255,0,0, -1,0,255,0,0,0,1,0)); // les deux lignes suivantes appliquent le filtre à votre objet d'affichage: filters.push (cmf); myDisplayObject.filters = filtres;

Maintenant, regardons le filtre de convolution.

Le filtre de convolution

De la référence de classe d'Adobe:

Une convolution combine les pixels de l'image d'entrée avec les pixels voisins pour produire une image. Une grande variété d'effets sur l'image peut être obtenue par des convolutions, notamment le flou, la détection des contours, la netteté, le gaufrage et le biseautage..

ConvolutionFilter parcourt tous les pixels d'un objet d'affichage. Pour chacun d'eux, il utilise la valeur centrale de la matrice comme valeur du pixel actuel manipulé. Par exemple, dans une matrice 3 x 3, la valeur centrale est à (1, 1). Il multiplie ensuite les valeurs de la matrice par les pixels environnants et ajoute les valeurs résultantes pour tous les pixels pour obtenir la valeur du pixel central résultant..

Comprendre le calcul exact sous la matrice de convolution vaut un nouvel article, je ne vais donc pas couvrir tout cela ici. Si vous souhaitez en savoir plus, consultez ce post sur adobe.com..

Cependant, un simple jeu avec les valeurs finira par vous donner tous les effets possibles que vous pouvez obtenir. Et ce sera amusant :) Voyons ce que nous pouvons faire!

Expérience

Le filtre de convolution utilise une matrice, tout comme le filtre de matrice de couleurs. De nouveau, les valeurs varient entre -255 et 255. Et encore une fois, vous obtenez la plupart des effets intéressants lorsque vous combinez des valeurs négatives avec des valeurs positives..

Permettez-moi de partager avec vous mes observations sur la façon dont cette chose fonctionne. Essayez d'augmenter certaines valeurs aléatoires de la matrice. Quel que soit votre choix, cela éclaircira la photo; si vous voulez que l'image reste à la luminosité normale, assurez-vous que la valeur de "diviseur" est égale à la somme de toutes les valeurs de la matrice.

Maintenant, si vous essayez de réduire une valeur aléatoire en dessous de zéro tout en maintenant au moins une autre valeur au dessus de zéro, vous obtenez quelque chose. Cela affecte vos bords:

En voici une belle: envie de ressembler à un soldat? :) Essayez ces valeurs:

Abaissez maintenant la valeur du "diviseur" à "-1" pour devenir un soldat en mission de nuit.

Beaucoup de choses peuvent être réalisées si vous maintenez un peu plus le bouton de votre souris :) Baissez et augmentez certaines valeurs à l'extrême. N'oubliez pas de régler le "diviseur" - c'est crucial. Agrandir votre matrice. Faites-le 5x5, par exemple.

Application dans le monde réel

Pour appliquer l’effet dans votre propre code, utilisez la commande filtres comme vous l'avez fait pour ColorMatrixFilter:

 // première importation de ConvolutionFilter en haut de votre code: import flash.filters.ConvolutionFilter; //… plus tard: filtres var: Array = new Array (); // pour tout ce qui suit "= new", copiez et collez depuis la zone "Saisir le code" de EffectsTester: var cf: ConvolutionFilter = new ConvolutionFilter (3,3, new Array (1,0, -10, -2,3) , 1,6,1, -1), 0); // les deux lignes suivantes appliquent le filtre à votre objet d'affichage: filters.push (cf); myDisplayObject.filters = filtres;

Enfin: essayez de combiner les deux filtres.

 // commencez par importer les classes de filtre en haut de votre code: import flash.filters.ColorMatrixFilter; import flash.filters.ConvolutionFilter; //… plus tard: filtres var: Array = new Array (); // pour tout ce qui suit "= new", copiez et collez-le dans la zone "Saisir le code" de EffectsTester: var cmf: ColorMatrixFilter = new ColorMatrixFilter (new Array (-1,0,0,0,255,0, -1,0 , 0,255,0,0, -1,0,255,0,0,0,1,0)); var cf: ConvolutionFilter = new ConvolutionFilter (3,3, new Array (1,0, -10, -2,3,1,6,1, -1), 0); // les trois lignes suivantes appliquent les filtres à votre objet d'affichage: filters.push (cf); filters.push (cmf); myDisplayObject.filters = filtres;

Amusez-vous avec ces filtres et publiez tous les résultats que vous obtenez dans les commentaires! Merci d'avoir lu.