Comment : faire pivoter des couleurs

La rotation dans un espace de couleur à quatre dimensions est difficile à visualiser. Nous pouvons faciliter la visualisation de la rotation en acceptant de conserver l’un des composants de couleur fixes. Supposons que nous acceptions de conserver le composant alpha fixe à 1 (entièrement opaque). Ensuite, nous pouvons visualiser un espace de couleurs tridimensionnel avec des axes rouges, verts et bleus, comme illustré dans l’illustration suivante.

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

Une couleur peut être considérée comme un point dans l’espace 3D. Par exemple, le point (1, 0, 0) dans l’espace représente la couleur rouge et le point (0, 1, 0) dans l’espace représente la couleur verte.

L’illustration suivante montre ce qu’il signifie pour faire pivoter la couleur (1, 0, 0) à travers un angle de 60 degrés dans le plan rouge-vert. La rotation dans un plan parallèle au plan rouge-vert peut être considérée comme une rotation sur l’axe bleu.

Illustration that shows rotation about the blue axis.

L’illustration suivante montre comment initialiser une matrice de couleurs pour effectuer des rotations sur chacun des trois axes de coordonnées (rouge, vert, bleu) :

Initialize a color matrix to perform rotations about three axes.

Exemple

L’exemple suivant prend une image qui est toute une couleur (1, 0, 0,6) et applique une rotation de 60 degrés sur l’axe bleu. L’angle de la rotation est balayé dans un plan parallèle au plan rouge-vert.

L’illustration suivante montre l’image d’origine à gauche et l’image pivotée en couleur à droite :

Illustration that shows original image and color-rotated image.

L’illustration suivante montre une visualisation de la rotation des couleurs effectuée dans le code suivant :

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

Compilation du code

L'exemple précédent est conçu pour une utilisation avec Windows Forms et nécessite PaintEventArgse, qui est un paramètre du gestionnaire d'événements Paint. Remplacez par RotationInput.bmp un nom de fichier image et un chemin valides sur votre système.

Voir aussi