Compartir a través de


Cómo: Girar colores

La rotación en un espacio de color de cuatro dimensiones es difícil de visualizar. Podemos facilitar la visualización de la rotación aceptando mantener uno de los componentes de color fijos. Supongamos que estamos de acuerdo en mantener el componente alfa fijo en 1 (totalmente opaco). A continuación, podemos visualizar un espacio de color tridimensional con ejes rojo, verde y azul, como se muestra en la ilustración siguiente.

Ilustración que muestra la rotación con ejes rojo, verde y azul.

Un color se puede considerar como un punto en el espacio 3D. Por ejemplo, el punto (1, 0, 0) en el espacio representa el color rojo y el punto (0, 1, 0) en el espacio representa el color verde.

En la siguiente ilustración se muestra lo que significa girar el color (1, 0, 0) a través de un ángulo de 60 grados en el plano de Red-Green. La rotación en un plano paralelo al plano Red-Green se puede considerar como rotación sobre el eje azul.

Ilustración que muestra el giro sobre el eje azul.

En la ilustración siguiente se muestra cómo inicializar una matriz de colores para realizar rotaciones sobre cada uno de los tres ejes de coordenadas (rojo, verde, azul):

Inicialice una matriz de colores para realizar rotaciones sobre tres ejes.

Ejemplo

En el ejemplo siguiente se toma una imagen que es todo un color (1, 0, 0,6) y aplica un giro de 60 grados sobre el eje azul. El ángulo de la rotación se arrastra en un plano que es paralelo al plano rojo-verde.

En la ilustración siguiente se muestra la imagen original a la izquierda y la imagen girada por color a la derecha:

Ilustración que muestra la imagen original y la imagen con rotación de color.

En la ilustración siguiente se muestra una visualización de la rotación de colores realizada en el código siguiente:

Ilustración que muestra la visualización de la rotación de colores.

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

Compilar el código

El ejemplo anterior está diseñado para su uso con Windows Forms y requiere PaintEventArgse, que es un parámetro del Paint controlador de eventos. Reemplace RotationInput.bmp por un nombre de archivo de imagen y una ruta de acceso válidos en su sistema.

Consulte también