Share via


Procedura: utilizzare una matrice di colori per trasformare un singolo colore

GDI+ fornisce le classi e Bitmap per l'archiviazione Image e la modifica delle immagini. Image gli oggetti 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 rappresenta 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 un colore rosso o blu, ma ha verde a piena intensità.

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

È possibile applicare trasformazioni lineari (rotazione, ridimensionamento e like) a vettori di colore moltiplicando i vettori di colore per una matrice 4×4. Tuttavia, non è possibile usare una matrice 4×4 per eseguire una conversione (non lineare). Se si aggiunge una quinta coordinata fittizia (ad esempio, il numero 1) a ognuno dei vettori di colore, è possibile usare una matrice 5×5 per applicare qualsiasi combinazione di trasformazioni e traduzioni lineari. Una trasformazione costituita da una trasformazione lineare seguita da una traduzione è detta trasformazione affine.

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

  1. Raddoppiare il componente rosso

  2. Aggiungere 0.2 ai componenti rosso, verde e blu

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

Screenshot of a transformation multiplication matrix.

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 nella terza colonna della matrice M è indicata 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 per la matrice di identità, il vettore di colore non cambia. Un modo pratico per formare la matrice di una trasformazione del colore consiste nell'iniziare con la matrice di identità e apportare una piccola modifica che produce la trasformazione desiderata.

Screenshot of a 5x5 identity matrix for color transformation.

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

Esempio

Nell'esempio seguente viene accettata un'immagine che è tutto un colore (0.2, 0.0, 0.4, 1.0) e applica la trasformazione descritta nei paragrafi precedenti.

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

A purple square on the left and a fuchsia square on the right.

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

  1. Inizializzare un ColorMatrix oggetto .

  2. Creare un ImageAttributes oggetto e passare l'oggetto ColorMatrix al SetColorMatrix metodo dell'oggetto ImageAttributes .

  3. Passare l'oggetto ImageAttributes al DrawImage metodo di un Graphics oggetto .

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)

Compilazione del codice

L'esempio precedente è progettato per l'uso con Windows Form e richiede PaintEventArgse, un parametro del gestore eventi Paint.

Vedi anche