Procedura: Ruotare i colori

La rotazione in uno spazio di colore tridimensionale è 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 dei colori tridimensionale con assi rosso, verde e blu, come illustrato nella figura seguente.

Illustrazione che mostra la rotazione con assi rosso, verde e blu.

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 Red-Green. La rotazione in un piano parallelo al piano Red-Green può essere considerata come rotazione sull'asse blu.

Figura che mostra la rotazione sull'asse blu.

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

Inizializzare una matrice di colori per eseguire rotazioni su tre assi.

Esempio

L'esempio seguente accetta 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:

Illustrazione che mostra l'immagine originale e l'immagine ruotata a colori.

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

Illustrazione che mostra la visualizzazione della rotazione dei colori.

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 e un percorso di file di immagine validi nel sistema.

Vedi anche