Share via


Verwenden einer Farbmatrix zum Transformieren einer einzelnen Farbe

Windows GDI+ stellt die Image - und Bitmap-Klassen zum Speichern und Bearbeiten von Bildern bereit. Bild - und Bitmapobjekte speichern die Farbe jedes Pixels als 32-Bit-Zahl: jeweils 8 Bit für Rot, Grün, Blau und Alpha. Jede der vier Komponenten ist eine Zahl von 0 bis 255, wobei 0 keine Intensität darstellt und 255 die volle Intensität darstellt. Die Alpha-Komponente gibt die Transparenz der Farbe an: 0 ist vollständig transparent, 255 ist vollständig undurchsichtig.

Ein Farbvektor ist ein 4-Tupel der Form (Rot, Grün, Blau, Alpha). Der Farbvektor (0, 255, 0, 255) eine stellt beispielsweise eine undurchsichtige Farbe ohne Rot und Blau dar, die aber Grün in voller Intensität aufweist.

Eine andere Konvention für die Darstellung von Farben verwendet die Zahl 1 für die maximale Intensität und die Zahl 0 für die minimale Intensität. Bei Verwendung dieser Konvention würde die im vorherigen Absatz beschriebene Farbe durch den Vektor (0, 1, 0, 1) dargestellt. GDI+ verwendet die Konvention mit 1 als voller Intensität, wenn Farbtransformationen ausgeführt werden.

Sie können lineare Transformationen (Drehung, Skalierung usw.) auf Farbvektoren anwenden, indem Sie mit einer 4 ×4-Matrix multiplizieren. Sie können jedoch keine 4 ×4-Matrix verwenden, um eine Übersetzung (nicht linear) durchzuführen. Wenn Sie jedem Farbvektor eine dummy fünfte Koordinate (z. B. die Zahl 1) hinzufügen, können Sie eine Matrix mit 5 ×5 verwenden, um eine beliebige Kombination linearer Transformationen und Übersetzungen anzuwenden. Eine Transformation, die aus einer linearen Transformation, gefolgt von einer Translation, besteht, wird als affine Transformation bezeichnet. Eine 5 ×5-Matrix, die eine affine Transformation darstellt, wird als homogene Matrix für eine 4-Raum-Transformation bezeichnet. Das Element in der fünften Zeile und fünften Spalte einer homogenen Matrix von 5 ×5 muss 1 sein, und alle anderen Einträge in der fünften Spalte müssen 0 sein.

Angenommen, Sie möchten beispielsweise mit der Farbe (0.2, 0.0, 0.4, 1.0) beginnen und die folgenden Transformationen anwenden:

  1. Verdoppeln der Rot-Komponente
  2. Hinzufügen von 0,2 (0.2) zu den Komponenten Rot, Grün und Blau

Die folgende Matrixmultiplikation führt das Transformationspaar in der aufgeführten Reihenfolge aus.

Abbildung einer 5x1-Matrix mit Zahlen multipliziert mit einer 5x5-Matrix zum Erstellen einer neuen 5x1-Matrix

Die Elemente einer Farbmatrix werden nach Zeile und Spalte indiziert (nullbasiert). Beispielsweise wird der Eintrag in der fünften Zeile und dritten Spalte der Matrix M durch „M[4][2]“ bezeichnet.

Die Identitätsmatrix 5 ×5 (in der folgenden Abbildung dargestellt) enthält 1 auf der Diagonale und überall sonst 0s. Wenn Sie einen Farbvektor mit der Identitätsmatrix multiplizieren, ändert sich der Farbvektor nicht. Eine bequeme Möglichkeit, um die Matrix einer Farbtransformation zu bilden, besteht darin, mit der Identitätsmatrix zu beginnen und eine kleine Änderung vorzunehmen, die die gewünschte Transformation erzeugt.

Abbildung einer 5x5-Identitätsmatrix; 1s auf der Diagonale oben links nach unten rechts und 0s überall sonst

Ausführlichere Erläuterungen zu Matrizen und Transformationen finden Sie unter Koordinatensysteme und Transformationen.

Im folgenden Beispiel wird ein Bild verwendet, das vollständig einfarbig (0.2, 0.0, 0.4, 1.0) ist, und die in den vorherigen Absätzen beschriebene Transformation darauf angewendet.

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);

In der folgenden Abbildung wird links das Originalbild und rechts das transformierte Bild gezeigt.

Abbildung eines Rechtecks, das mit einer dunklen Volltonfarbe gefüllt ist und dann mit einer helleren Volltonfarbe gefüllt ist

Der Code im vorherigen Beispiel verwendet die folgenden Schritte, um die Neufärbung auszuführen:

  1. Initialisieren Sie eine ColorMatrix-Struktur .
  2. Erstellen Sie ein ImageAttributes-Objekt , und übergeben Sie die Adresse der ColorMatrix-Struktur an die ImageAttributes::SetColorMatrix-Methode des ImageAttributes-Objekts .
  3. Übergeben Sie die Adresse des ImageAttributes-Objekts an die DrawImage Methods-Methode eines Graphics-Objekts .