Comment : utiliser une matrice de couleurs pour transformer une couleur unique
GDI+ fournit les classes Image et Bitmap pour le stockage et la manipulation des images. Les objets Image et Bitmap stockent la couleur de chaque pixel comme un nombre 32 bits : 8 bits pour chaque rouge, vert, bleu et alpha. Chacun des quatre composants est un nombre compris entre 0 et 255, 0 représentant une intensité nulle et 255 une intensité maximale. Le composant alpha spécifie la transparence de la couleur : 0 est totalement transparent et 255 totalement opaque.
Un vecteur de couleur est un 4-tuple de forme (rouge, vert, bleu, alpha). Par exemple, le vecteur de couleur (0, 255, 0, 255) représente une couleur opaque dépourvue de rouge ou de bleu, mais avec une intensité de vert maximale.
Une autre convention de représentation des couleurs utilise le nombre 1 pour l'intensité maximale. Avec cette convention, la couleur décrite dans le paragraphe précédent est représentée par le vecteur (0, 1, 0, 1). GDI+ utilise la convention de 1 comme intensité complète lorsqu'il exécute des transformations de couleur.
Vous pouvez appliquer des transformations linéaires (rotation, mise à l'échelle et autres) aux vecteurs de couleurs en multipliant ces vecteurs par une matrice 4x4. Toutefois, vous ne pouvez pas utiliser de matrice 4x4 pour effectuer une traduction (non linéaire). Si vous ajoutez une cinquième coordonnée fictive (par exemple, le nombre 1) à chaque vecteur de couleur, vous pouvez utiliser une matrice 5x5 pour appliquer des combinaisons de transformations et de traductions linéaires. Une transformation comprenant une transformation linéaire suivie d'une translation s'appelle une transformation affine.
Supposez, par exemple, que vous commenciez par la couleur (0.2, 0.0, 0.4, 1.0) et appliquiez les transformations suivantes :
Doubler la composante rouge.
Ajouter 0,2 aux composantes rouge, vert et bleu.
La multiplication de la matrice suivante va effectuer la paire de transformations dans l'ordre indiqué.
Les éléments d'une matrice de couleurs sont indexés (base zéro) par ligne, puis par colonne. Par exemple, l'entrée sur la cinquième ligne et la troisième colonne de la matrice M est représentée par M[4][2].
La matrice d'identité 5x5 (présentée dans l'illustration ci-après) possède des 1 sur la diagonale et des 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é, puis à apporter une légère modification pour générer la transformation souhaitée.
Pour une présentation détaillée des matrices et des transformations, consultez Systèmes de coordonnées et transformations.
Exemple
L'exemple suivant prend une image en une seule 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 sur la gauche et l'image transformée sur la droite.
Pour effectuer le recoloriage, le code de l'exemple suivant effectue les étapes ci-après :
Initialise un objet ColorMatrix.
Crée un objet ImageAttributes et passe l'objet ColorMatrix à la méthode SetColorMatrix de l'objet ImageAttributes.
Passe l'objet ImageAttributes à la méthode DrawImage d'un objet Graphics.
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)
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);
Compilation du code
L'exemple précédent est destiné à une utilisation avec Windows Forms et nécessite PaintEventArgs e, qui est un paramètre du gestionnaire d'événements Paint.