Share via


Uso di una matrice di colori per trasformare un singolo colore

Windows GDI+ fornisce le classi Image e Bitmap per archiviare e modificare le immagini. Gli oggetti Image e Bitmap archiviano il colore di ogni pixel come numero a 32 bit: 8 bit ciascuno per rosso, verde, blu e alfa. Ognuno dei quattro componenti è un numero compreso tra 0 e 255, con 0 che rappresenta nessuna intensità e 255 che rappresentano l'intensità completa. Il componente alfa specifica la trasparenza del colore: 0 è completamente trasparente e 255 è completamente opaco.

Un vettore di colore è una tupla a 4 della forma (rosso, verde, blu, alfa). Ad esempio, il vettore di colore (0, 255, 0, 255) rappresenta un colore opaco che non ha alcun colore rosso o blu, ma ha verde a piena intensità.

Un'altra convenzione per rappresentare i colori usa il numero 1 per l'intensità massima e il numero 0 per l'intensità minima. Usando tale convenzione, il colore descritto nel paragrafo precedente sarebbe rappresentato dal vettore (0, 1, 0, 1, 1). GDI+ usa la convenzione 1 come intensità completa quando esegue trasformazioni di colore.

È possibile applicare trasformazioni lineari (rotazione, ridimensionamento e simile) a vettori di colore moltiplicando in base a una matrice di 4 ×4. Tuttavia, non è possibile usare una matrice di 4 ×4 per eseguire una traduzione (non lineare). Se si aggiunge una quinta coordinata fittizia (ad esempio, il numero 1) a ognuno dei vettori di colore, è possibile usare una matrice di 5 ×5 per applicare qualsiasi combinazione di trasformazioni e traduzioni lineari. Una trasformazione costituita da una trasformazione lineare seguita da una traduzione è denominata trasformazione affine. Una matrice di 5 ×5 che rappresenta una trasformazione affine viene chiamata matrice omogenea per una trasformazione dello spazio a 4. L'elemento nella quinta riga e nella quinta colonna di una matrice omogenea di 5 ×5 deve essere 1 e tutte le altre voci della quinta colonna devono essere 0.

Si supponga, ad esempio, di voler iniziare con il colore (0.2, 0.0, 0.4, 1.0) e applicare le trasformazioni seguenti:

  1. Doppio componente rosso
  2. Aggiungere 0.2 ai componenti rossi, verdi e blu

La moltiplicazione della matrice seguente eseguirà la coppia di trasformazioni nell'ordine elencato.

figura che mostra una matrice 5x1 di numeri moltiplicati per una matrice 5x5 per creare una nuova matrice 5x1

Gli elementi di una matrice di colori vengono indicizzati (in base zero) per riga e quindi colonna. Ad esempio, la voce nella quinta riga e la terza colonna della matrice M viene denotata da M[4][2].

La matrice di identità 5 ×5 (illustrata nella figura seguente) ha 1s sulla diagonale e 0 ovunque. Se si moltiplica un vettore di colore in base alla matrice di identità, il vettore di colore non cambia. Un modo pratico per formare la matrice di una trasformazione colore consiste nell'iniziare con la matrice di identità e apportare una piccola modifica che produce la trasformazione desiderata.

illustrazione che mostra una matrice di identità 5x5; 1s nella parte superiore sinistra a diagonale inferiore destra e 0 ovunque

Per una discussione più dettagliata delle matrici e delle trasformazioni, vedere Sistemi di coordinate e trasformazioni.

L'esempio seguente accetta un'immagine che corrisponde a un colore (0.2, 0.0, 0.4, 1.0) e applica la trasformazione descritta nei paragrafi precedenti.

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);

La figura seguente mostra l'immagine originale a sinistra e l'immagine trasformata a destra.

illustrazione che mostra un rettangolo riempito da un colore a tinta unita scuro e quindi uno riempito da un colore a tinta unita più chiaro

Il codice nell'esempio precedente usa i passaggi seguenti per eseguire la ricolorazione:

  1. Inizializzare una struttura ColorMatrix .
  2. Creare un oggetto ImageAttributes e passare l'indirizzo della struttura ColorMatrix al metodo ImageAttributes::SetColorMatrix dell'oggetto ImageAttributes .
  3. Passare l'indirizzo dell'oggetto ImageAttributes al metodo DrawImage Methods di un oggetto Graphics .