Vorgehensweise: Verwenden einer Farbmatrix zum Transformieren einer Farbe

GDI+ stellt die Klassen Image und Bitmap zum Speichern und Bearbeiten von Bildern bereit. Image- und Bitmap-Objekte speichern die Farbe jedes einzelnen 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 weitere Konvention zum Darstellen von Farben verwendet die Zahl 1 für volle 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 und ähnliches) auf Farbvektoren anwenden, indem Sie die Farbvektoren mit einer 4×4-Matrix multiplizieren. Sie können jedoch keine 4×4-Matrix verwenden, um eine Translation (nicht linear) auszuführen. Wenn Sie jedem der Farbvektoren eine fünfte Dummykoordinate (z. B. die Zahl 1) hinzufügen, können Sie eine 5×5-Matrix verwenden, um eine beliebige Kombination von linearen Transformationen und Translationen anzuwenden. Eine Transformation, die aus einer linearen Transformation, gefolgt von einer Translation, besteht, wird als affine Transformation bezeichnet.

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.

Screenshot of a transformation multiplication 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 5×5-Identitätsmatrix (in der folgenden Abbildung dargestellt) weist Einsen (1) auf der Diagonalen und Nullen (0) überall sonst auf. 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.

Screenshot of a 5x5 identity matrix for color transformation.

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

Beispiel

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.

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

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

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

  1. Initialisieren eines ColorMatrix-Objekts.

  2. Erstellen eines ImageAttributes-Objekts und Übergeben des ColorMatrix-Objekts an die SetColorMatrix-Methode des ImageAttributes-Objekts.

  3. Übergeben des ImageAttributes-Objekts an die DrawImage-Methode eines Graphics-Objekts.

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)

Kompilieren des Codes

Das obige Beispiel ist für die Verwendung in Windows Forms konzipiert und erfordert PaintEventArgse, einen Parameter des Paint-Ereignishandlers.

Siehe auch