Partager via


Utilisation d’une matrice de couleurs pour transformer une seule couleur

Windows GDI+ fournit les classes Image et Bitmap pour stocker et manipuler des images. Les objets Image et Bitmap 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, 0 ne 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 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 ni rouge ni bleu, mais a du vert à pleine intensité.

Une autre convention pour la représentation des couleurs utilise le nombre 1 pour l’intensité maximale et le nombre 0 pour l’intensité minimale. À l’aide de 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é totale lorsqu’il effectue des transformations de couleur.

Vous pouvez appliquer des transformations linéaires (rotation, mise à l’échelle, etc.) aux vecteurs de couleur en multipliant par une matrice 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 de 5 ×5 pour appliquer n’importe quelle combinaison de transformations linéaires et de traductions. Une transformation constituée d’une transformation linéaire suivie d’une traduction est appelée transformation affine. Une matrice de 5 ×5 qui représente une transformation affine est appelée matrice homogène pour une transformation à 4 espaces. L’élément de la cinquième ligne et de la cinquième colonne d’une matrice homogène de 5 ×5 doit être 1, et toutes les autres entrées de la cinquième colonne doivent être 0.

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

  1. Doubler le composant rouge
  2. Ajouter 0.2 aux composants rouge, vert et bleu

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

illustration montrant une matrice 5x1 de nombres multipliés par une matrice 5x5 pour créer une nouvelle matrice 5x1

Les éléments d’une matrice de couleurs 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 la matrice M est désignée par M[4][2].

La matrice d’identité 5 ×5 (illustrée dans l’illustration suivante) comporte 1 sur la diagonale et 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.

illustration montrant une matrice d’identité 5x5 ; 1s en diagonale de haut à gauche en bas à droite et 0 partout ailleurs

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

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

Image            image(L"InputColor.bmp");
ImageAttributes  imageAttributes;
UINT             width = image.GetWidth();
UINT             height = image.GetHeight();

ColorMatrix colorMatrix = {
   2.0f, 0.0f, 0.0f, 0.0f, 0.0f,
   0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
   0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
   0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
   0.2f, 0.2f, 0.2f, 0.0f, 1.0f};
   
imageAttributes.SetColorMatrix(
   &colorMatrix, 
   ColorMatrixFlagsDefault,
   ColorAdjustTypeBitmap);
   
graphics.DrawImage(&image, 10, 10);

graphics.DrawImage(
   &image, 
   Rect(120, 10, width, height),  // destination rectangle 
   0, 0,        // upper-left corner of source rectangle 
   width,       // width of source rectangle
   height,      // height of source rectangle
   UnitPixel,
   &imageAttributes);

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

illustration montrant un rectangle rempli par une couleur unie foncée, puis un rectangle rempli par une couleur unie plus claire

Le code de l’exemple précédent utilise les étapes suivantes pour effectuer la recolorisation :

  1. Initialisez une structure ColorMatrix .
  2. Créez un objet ImageAttributes et transmettez l’adresse de la structure ColorMatrix à la méthode ImageAttributes::SetColorMatrix de l’objet ImageAttributes .
  3. Passez l’adresse de l’objet ImageAttributes à la méthode DrawImage Methods d’un objet Graphics .