Procedura: ruotare i colori

La rotazione in uno spazio colore quattrodimensionale è difficile da visualizzare. È possibile semplificare la visualizzazione della rotazione accettando di mantenere fisso uno dei componenti di colore. Si supponga di accettare di mantenere fisso il componente alfa a 1 (completamente opaco). È quindi possibile visualizzare uno spazio colore tridimensionale con assi rosso, verde e blu, come illustrato nella figura seguente.

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

Un colore può essere considerato come un punto nello spazio 3D. Ad esempio, il punto (1, 0, 0) nello spazio rappresenta il colore rosso e il punto (0, 1, 0) nello spazio rappresenta il colore verde.

La figura seguente mostra cosa significa ruotare il colore (1, 0, 0) attraverso un angolo di 60 gradi nel piano Rosso-Verde. La rotazione in un piano parallelo al piano Rosso-Verde può essere considerata come rotazione sull'asse blu.

Illustration that shows rotation about the blue axis.

La figura seguente illustra come inizializzare una matrice di colori per eseguire rotazioni su ognuno dei tre assi delle coordinate (rosso, verde, blu):

Initialize a color matrix to perform rotations about three axes.

Esempio

Nell'esempio seguente viene accettata un'immagine che corrisponde a un colore (1, 0, 0,6) e applica una rotazione di 60 gradi sull'asse blu. L'angolo della rotazione viene spazzato via in un piano parallelo al piano rosso-verde.

La figura seguente mostra l'immagine originale a sinistra e l'immagine ruotata a colori a destra:

Illustration that shows original image and color-rotated image.

La figura seguente mostra una visualizzazione della rotazione dei colori eseguita nel codice seguente:

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

Compilazione del codice

L'esempio precedente è progettato per l'uso con Windows Form e richiede PaintEventArgse, un parametro del gestore eventi Paint. Sostituire RotationInput.bmp con un nome di file di immagine e un percorso valido nel sistema.

Vedi anche