Comment : utiliser une matrice de couleurs pour transformer une couleur unique

GDI+ fournit les classes et Bitmap les Image classes permettant de stocker et de manipuler des images. Image et Bitmap les objets stockent la couleur de chaque pixel sous la forme d’un nombre de 32 bits : 8 bits chacun pour le rouge, le vert, le bleu et l’alpha. Chacun des quatre composants est un nombre compris entre 0 et 255, avec 0 représentant aucune intensité et 255 représentant une intensité totale. Le composant alpha spécifie la transparence de la couleur : 0 est entièrement transparent et 255 est entièrement opaque.

Un vecteur de couleur est un tuple de 4 tuples de la forme (rouge, vert, bleu, alpha). Par exemple, le vecteur de couleur (0, 255, 0, 255) représente une couleur opaque qui n’a pas de rouge ou de bleu, mais qui a un vert à pleine intensité.

Une autre convention pour représenter les couleurs utilise le nombre 1 pour l’intensité totale. À l’aide de cette convention, la couleur décrite dans le paragraphe précédent serait représentée par le vecteur (0, 1, 0, 1). GDI+ utilise la convention de 1 comme intensité totale lorsqu’il effectue des transformations de couleur.

Vous pouvez appliquer des transformations linéaires (rotation, mise à l’échelle et similaires) à des vecteurs de couleur en multipliant les vecteurs de couleur par une matrice de 4×4. Toutefois, vous ne pouvez pas utiliser une matrice 4×4 pour effectuer une traduction (non linéaire). Si vous ajoutez une cinquième coordonnée factice (par exemple, le nombre 1) à chacun des vecteurs de couleur, vous pouvez utiliser une matrice 5×5 pour appliquer n’importe quelle combinaison de transformations linéaires et de traductions. Une transformation composée d’une transformation linéaire suivie d’une traduction est appelée transformation affine.

Par exemple, supposons que vous voulez commencer par la couleur (0.2, 0.0, 0.4, 1.0) et appliquer les transformations suivantes :

  1. Double du composant rouge

  2. Ajouter 0.2 aux composants rouges, verts et bleus

La multiplication de matrices suivante effectue la paire de transformations dans l’ordre indiqué.

Screenshot of a transformation multiplication matrix.

Les éléments d’une matrice de couleur sont indexés (de base zéro) par ligne, puis colonne. Par exemple, l’entrée dans la cinquième ligne et la troisième colonne de matrice M est indiquée par M[4][2].

La matrice d’identité 5×5 (illustrée dans l’illustration suivante) comporte 1 sur la diagonale et les 0 partout ailleurs. Si vous multipliez un vecteur de couleur par la matrice d’identité, le vecteur de couleur ne change pas. Un moyen pratique de former la matrice d’une transformation de couleur consiste à commencer par la matrice d’identité et à apporter une petite modification qui produit la transformation souhaitée.

Screenshot of a 5x5 identity matrix for color transformation.

Pour une présentation plus détaillée des matrices et des transformations, consultez La rubrique Systèmes et transformations de coordonnées.

Exemple

L’exemple suivant prend une image qui est toute une couleur (0.2, 0.0, 0.4, 1.0) et applique la transformation décrite dans les paragraphes précédents.

L’illustration suivante montre l’image d’origine à gauche et l’image transformée à droite.

A purple square on the left and a fuchsia square on the right.

Le code de l’exemple suivant utilise les étapes suivantes pour effectuer la recolorie :

  1. Initialisez un ColorMatrix objet.

  2. Créez un ImageAttributes objet et transmettez l’objet ColorMatrix à la SetColorMatrix méthode de l’objet ImageAttributes .

  3. Passez l’objet ImageAttributes à la DrawImage méthode d’un Graphics objet.

Image image = new Bitmap("InputColor.bmp");
ImageAttributes imageAttributes = new ImageAttributes();
int width = image.Width;
int height = image.Height;

float[][] colorMatrixElements = {
   new float[] {2,  0,  0,  0, 0},        // red scaling factor of 2
   new float[] {0,  1,  0,  0, 0},        // green scaling factor of 1
   new float[] {0,  0,  1,  0, 0},        // blue scaling factor of 1
   new float[] {0,  0,  0,  1, 0},        // alpha scaling factor of 1
   new float[] {.2f, .2f, .2f, 0, 1}};    // three translations of 0.2

ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

imageAttributes.SetColorMatrix(
   colorMatrix,
   ColorMatrixFlag.Default,
   ColorAdjustType.Bitmap);

e.Graphics.DrawImage(image, 10, 10);

e.Graphics.DrawImage(
   image,
   new Rectangle(120, 10, width, height),  // destination rectangle
   0, 0,        // upper-left corner of source rectangle
   width,       // width of source rectangle
   height,      // height of source rectangle
   GraphicsUnit.Pixel,
   imageAttributes);
Dim image As New Bitmap("InputColor.bmp")
Dim imageAttributes As New ImageAttributes()
Dim width As Integer = image.Width
Dim height As Integer = image.Height

' The following matrix consists of the following transformations:
' red scaling factor of 2
' green scaling factor of 1
' blue scaling factor of 1
' alpha scaling factor of 1
' three translations of 0.2
Dim colorMatrixElements As Single()() = { _
   New Single() {2, 0, 0, 0, 0}, _
   New Single() {0, 1, 0, 0, 0}, _
   New Single() {0, 0, 1, 0, 0}, _
   New Single() {0, 0, 0, 1, 0}, _
   New Single() {0.2F, 0.2F, 0.2F, 0, 1}}

Dim colorMatrix As New ColorMatrix(colorMatrixElements)

imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap)

e.Graphics.DrawImage(image, 10, 10)

e.Graphics.DrawImage( _
   image, _
   New Rectangle(120, 10, width, height), _
   0, _
   0, _
   width, _
   height, _
   GraphicsUnit.Pixel, _
   imageAttributes)

Compilation du code

L'exemple précédent est conçu pour une utilisation avec Windows Forms et nécessite PaintEventArgse, qui est un paramètre du gestionnaire d'événements Paint.

Voir aussi