Procedimiento para usar una matriz de colores para transformar un color único

GDI+ proporciona las clases Image y Bitmap para almacenar y manipular imágenes. Los objetos Image y Bitmap almacenan el color de cada píxel como un número de 32 bits: 8 bits para cada uno rojo, verde, azul y alfa. Cada uno de los cuatro componentes es un número comprendido entre 0 y 255; 0 no representa ninguna intensidad y 255 representa la intensidad completa. El componente alfa especifica la transparencia del color; 0 es totalmente transparente y 255 es totalmente opaco.

Un vector de color es una tupla de 4 con el formato "(rojo, verde, azul, alfa)". Por ejemplo, el vector de color (0, 255, 0, 255) representa un color opaco que no tiene rojo ni azul, pero sí verde con intensidad completa.

Otra convención para representar colores usa el número 1 para la intensidad completa. Con esa convención, el color descrito en el párrafo anterior se representaría mediante el vector (0, 1, 0, 1). GDI+ usa la convención de 1 como intensidad completa cuando realiza transformaciones de color.

Puede aplicar transformaciones lineales (rotación, escala y similares) a vectores de color si multiplica los vectores de color por una matriz de 4 × 4, pero no puede usar una matriz de 4 × 4 para realizar una traslación (no lineal). Si agrega una quinta coordenada ficticia (por ejemplo, el número 1) a cada uno de los vectores de color, puede usar una matriz de 5 × 5 para aplicar cualquier combinación de transformaciones y traslaciones lineales. Una transformación que consta de una transformación lineal seguida de una traslación se denomina "transformación afín".

Por ejemplo, supongamos que quiere empezar con el color (0.2, 0.0, 0.4, 1.0) y aplicar las siguientes transformaciones:

  1. Duplique el componente rojo.

  2. Agregue 0.2 a los componentes rojo, verde y azul.

La multiplicación de matrices siguiente realizará el par de transformaciones en el orden indicado.

Captura de pantalla de una matriz de multiplicación de transformación.

Los elementos de una matriz de colores se indexan (con base cero) por fila y, luego, por columna. Por ejemplo, la entrada de la quinta fila y la tercera columna de matriz M se indica mediante M[4][2].

La matriz de identidad de 5 × 5 (que se muestra en la ilustración siguiente) tiene unos en la diagonal y ceros en los demás lugares. Si multiplica un vector de color por la matriz de identidad, el vector de color no cambia. Una forma cómoda de formar la matriz de una transformación de color es comenzar con la matriz de identidad y realizar un pequeño cambio que genere la transformación deseada.

Captura de pantalla de una matriz de identidad 5x5 para la transformación de color.

Para obtener una explicación más detallada de las matrices y las transformaciones, consulte Sistemas de coordenadas y transformaciones.

Ejemplo

En el ejemplo siguiente se toma una imagen que es todo un color (0.2, 0.0, 0.4, 1.0) y se aplica la transformación descrita en los párrafos anteriores.

En la ilustración siguiente se muestra la imagen original a la izquierda y la imagen transformada a la derecha.

Un cuadrado púrpura a la izquierda y un cuadrado fucsia a la derecha.

El código del ejemplo siguiente usa los pasos siguientes para realizar el cambio de color:

  1. Inicializa un objeto ColorMatrix.

  2. Crea un objeto ImageAttributes y pasa el objeto ColorMatrix al método SetColorMatrix del objeto ImageAttributes.

  3. Pasa el objeto ImageAttributes al método DrawImage de un objeto Graphics.

Image image = new Bitmap("InputColor.bmp");
ImageAttributes imageAttributes = new ImageAttributes();
int width = image.Width;
int height = image.Height;

float[][] colorMatrixElements = {
   new float[] {2,  0,  0,  0, 0},        // red scaling factor of 2
   new float[] {0,  1,  0,  0, 0},        // green scaling factor of 1
   new float[] {0,  0,  1,  0, 0},        // blue scaling factor of 1
   new float[] {0,  0,  0,  1, 0},        // alpha scaling factor of 1
   new float[] {.2f, .2f, .2f, 0, 1}};    // three translations of 0.2

ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

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

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

e.Graphics.DrawImage(
   image,
   new Rectangle(120, 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);
Dim image As New Bitmap("InputColor.bmp")
Dim imageAttributes As New ImageAttributes()
Dim width As Integer = image.Width
Dim height As Integer = image.Height

' The following matrix consists of the following transformations:
' red scaling factor of 2
' green scaling factor of 1
' blue scaling factor of 1
' alpha scaling factor of 1
' three translations of 0.2
Dim colorMatrixElements As Single()() = { _
   New Single() {2, 0, 0, 0, 0}, _
   New Single() {0, 1, 0, 0, 0}, _
   New Single() {0, 0, 1, 0, 0}, _
   New Single() {0, 0, 0, 1, 0}, _
   New Single() {0.2F, 0.2F, 0.2F, 0, 1}}

Dim colorMatrix As New ColorMatrix(colorMatrixElements)

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

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

e.Graphics.DrawImage( _
   image, _
   New Rectangle(120, 10, width, height), _
   0, _
   0, _
   width, _
   height, _
   GraphicsUnit.Pixel, _
   imageAttributes)

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 controlador de eventos Paint.

Consulte también