Compartir a través de


Uso de una matriz de colores para transformar un color único

Windows 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 cada uno para 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 máxima y el número 0 para la intensidad mínima. 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, escalado y similares) a vectores de color multiplicando por una matriz de 4 ×4. Sin embargo, no puede usar una matriz de 4 ×4 para realizar una traducción (no lineal). Si agrega una quinta coordenada ficticía (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 traslación se denomina "transformación afín". Una matriz de 5 ×5 que representa una transformación afín se denomina matriz homogénea para una transformación de 4 espacios. El elemento de la quinta fila y la quinta columna de una matriz homogénea de 5 ×5 debe ser 1 y todas las demás entradas de la quinta columna deben ser 0.

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.

ilustración en la que se muestra una matriz de números de 5x1 multiplicada por una matriz de 5x5 para crear una nueva matriz de 5 x 1

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 la matriz M se indica mediante M[4][2].

La matriz de identidad de 5 ×5 (que se muestra en la ilustración siguiente) tiene 1s en la diagonal y 0 en cualquier otro lugar. 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.

ilustración que muestra una matriz de identidad de 5x5; 1s en la parte superior izquierda a la diagonal inferior derecha y 0s en cualquier otro lugar

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

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.

Image            image(L"InputColor.bmp");
ImageAttributes  imageAttributes;
UINT             width = image.GetWidth();
UINT             height = image.GetHeight();

ColorMatrix colorMatrix = {
   2.0f, 0.0f, 0.0f, 0.0f, 0.0f,
   0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
   0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
   0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
   0.2f, 0.2f, 0.2f, 0.0f, 1.0f};
   
imageAttributes.SetColorMatrix(
   &colorMatrix, 
   ColorMatrixFlagsDefault,
   ColorAdjustTypeBitmap);
   
graphics.DrawImage(&image, 10, 10);

graphics.DrawImage(
   &image, 
   Rect(120, 10, width, height),  // destination rectangle 
   0, 0,        // upper-left corner of source rectangle 
   width,       // width of source rectangle
   height,      // height of source rectangle
   UnitPixel,
   &imageAttributes);

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

ilustración que muestra un rectángulo lleno de un color sólido oscuro y, a continuación, uno relleno por un color sólido más claro

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

  1. Inicialice una estructura ColorMatrix .
  2. Cree un objeto ImageAttributes y pase la dirección de la estructura ColorMatrix al método ImageAttributes::SetColorMatrix del objeto ImageAttributes .
  3. Pase la dirección del objeto ImageAttributes al método DrawImage Methods de un objeto Graphics .