Compartir a través de


Cómo: Usar una matriz de colores para transformar un único color

GDI+ proporciona las Image clases y Bitmap para almacenar y manipular imágenes. Image y Bitmap los objetos almacenan el color de cada píxel como un número de 32 bits: 8 bits cada uno para rojo, verde, azul y alfa. Cada uno de los cuatro componentes es un número comprendido entre 0 y 255, con 0 que no representa ninguna intensidad y 255 que 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 de la forma (rojo, verde, azul, alfa). Por ejemplo, el vector de color (0, 255, 0, 255) representa un color opaco que no tiene color rojo o azul, pero tiene verde a plena intensidad.

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, 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 multiplicando los vectores de color por una matriz 4×4. Sin embargo, no puede usar una matriz 4×4 para realizar una traducció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 traducciones lineales. Una transformación que consta de una transformación lineal seguida de una traducción se denomina transformación afín.

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

  1. Duplicar el componente rojo

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

La multiplicación de matriz 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 (basados en cero) por fila y, a continuación, 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 5×5 (que se muestra en la ilustración siguiente) tiene 1s en la diagonal y 0 en cualquier otra parte. 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 matrices y 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 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 fuchsia a la derecha.

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

  1. Inicialice un ColorMatrix objeto .

  2. Cree un ImageAttributes objeto y pase el ColorMatrix objeto al SetColorMatrix método del ImageAttributes objeto .

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

Consulte también