Vorgehensweise: Drehen von Farben

In einem vierdimensionalen Farbraum sind Drehungen schwierig zu visualisieren. Wir können das Visualisieren von Drehungen vereinfachen, indem wir eine der Farbkomponenten festlegen. Angenommen, wir legen die Alphakomponente auf 1 (vollkommen undurchsichtig) fest. Dann können wir (wie in der folgenden Abbildung dargestellt) einen dreidimensionalen Farbraum mit roten, grünen und blauen Achsen visualisieren.

Illustration that shows rotation with red, green, and blue axes.

Sie können sich eine Farbe als Punkt in einem 3D-Raum vorstellen. Beispielsweise stellt der Punkt (1, 0, 0) im Raum die Farbe Rot und der Punkt (0, 1, 0) im Raum die Farbe Grün dar.

In den folgenden Abbildungen wird gezeigt, was bei einer Drehung der Farbe (1, 0, 0) um einen Winkel von 60 Grad in der Rot-Grün-Ebene geschieht. Die Drehung auf einer Ebene, die parallel zur Rot-Grün-Ebene ist, kann als Drehung der blauen Achse verstanden werden.

Illustration that shows rotation about the blue axis.

In der folgenden Abbildung wird veranschaulicht, wie Sie eine Farbmatrix initialisieren können, um Drehungen um jede der drei Koordinatenachsen (Rot, Grün, Blau) durchzuführen:

Initialize a color matrix to perform rotations about three axes.

Beispiel

Im folgenden Beispiel wird ein Bild verwendet, das nur die Farbe (1, 0, 0.6) hat, und es wird eine 60 Grad-Drehung um die blaue Achse durchgeführt. Der Winkel der Drehung befindet sich in einer Ebene, die parallel zur Rot-Grün-Ebene liegt.

In der folgenden Abbildung wird links das ursprüngliche Bild und rechts das Bild mit Farbdrehung gezeigt:

Illustration that shows original image and color-rotated image.

In der folgenden Abbildung wird eine Visualisierung der Farbdrehung gezeigt, die im folgenden Code durchgeführt wird:

Illustration that shows the visualization of the color rotation.

private void RotateColors(PaintEventArgs e)
{
    Bitmap image = new Bitmap("RotationInput.bmp");
    ImageAttributes imageAttributes = new ImageAttributes();
    int width = image.Width;
    int height = image.Height;
    float degrees = 60f;
    double r = degrees * System.Math.PI / 180; // degrees to radians

    float[][] colorMatrixElements = {
        new float[] {(float)System.Math.Cos(r),  (float)System.Math.Sin(r),  0,  0, 0},
        new float[] {(float)-System.Math.Sin(r),  (float)-System.Math.Cos(r),  0,  0, 0},
        new float[] {0,  0,  2,  0, 0},
        new float[] {0,  0,  0,  1, 0},
        new float[] {0, 0, 0, 0, 1}};

    ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

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

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

    e.Graphics.DrawImage(
       image,
       new Rectangle(150, 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);
}
Private Sub RotateColors(ByVal e As PaintEventArgs)
    Dim image As Bitmap = New Bitmap("RotationInput.bmp")
    Dim imageAttributes As New ImageAttributes()
    Dim width As Integer = image.Width
    Dim height As Integer = image.Height
    Dim degrees As Single = 60.0F
    Dim r As Double = degrees * System.Math.PI / 180 ' degrees to radians
    Dim colorMatrixElements As Single()() = { _
       New Single() {CSng(System.Math.Cos(r)), _
                     CSng(System.Math.Sin(r)), 0, 0, 0}, _
       New Single() {CSng(-System.Math.Sin(r)), _
                     CSng(-System.Math.Cos(r)), 0, 0, 0}, _
       New Single() {0, 0, 2, 0, 0}, _
       New Single() {0, 0, 0, 1, 0}, _
       New Single() {0, 0, 0, 0, 1}}

    Dim colorMatrix As New ColorMatrix(colorMatrixElements)

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

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

    ' Pass in the destination rectangle (2nd argument), the upper-left corner 
    ' (3rd and 4th arguments), width (5th argument),  and height (6th 
    ' argument) of the source rectangle.
    e.Graphics.DrawImage( _
       image, _
       New Rectangle(150, 10, width, height), _
       0, 0, _
       width, _
       height, _
       GraphicsUnit.Pixel, _
       imageAttributes)
End Sub

Kompilieren des Codes

Das obige Beispiel ist für die Verwendung in Windows Forms konzipiert und erfordert PaintEventArgse, einen Parameter des Paint-Ereignishandlers. Ersetzen Sie RotationInput.bmp durch einen Bilddateinamen und einen Pfad, die auf Ihrem System gültig sind.

Siehe auch