ColorMatrix – Effetti Pixel per Pixel in C#

dotnetLavorando in .NET può capitare spesso di imbattersi con lavori che richiedano di manipolare delle immagini e talvolta può capitare di volere applicare dei filtri alle suddette. Il metodo più immediato che può venire in mente è quello di effettuare delle modifiche pixel per pixel all’immagine, scorrendo quella di partenza su entrambe gli assi X ed Y. Cerchiamo di comprendere meglio questo concetto partendo dalla teoria.

Quando noi scattiamo una fotografia, ad esempio questa, il sensore CCD della nostra fotocamera cattura ogni singola informazione luminosa proveniente dall’ottica in modo ordinato ed in base alla sua risoluzione restituisce una serie di bit che solitamente compongono il formato RAW della fotografia che vengono poi immagazzinati sotto forma di un’immagine JPEG, ad esempio questa:

paesaggio-germania

Una volta che riportiamo questa fotografia su uno schermo qualsiasi, i bit di colore devono venire nuovamente riclassificati secono i loro valori fondamentali, il Rosso, il Verde ed il Blu (in inglese RGB) in modo che il nostro occhio possa vedere le differenze tra un punto e l’altro. A tal proposito, quando fu inventato il primo schermo a colori, pensarono bene di accostare una moltitudine di punti (i pixel) costituiti a loro volta da 3 puntini luminosi guarda caso rossi, verdi e blu e dare loro tanta più illuminazione quanta ne è specificata nell’informazione da rappresentare.

Questa immagine serve per far capire meglio come vengono rappresentati i colori sugli schermi:

pixel

Se non vi è molto chiaro il concetto, vi consiglio di leggervi l’ottimo articolo di Wikipedia sui Pixel. Ora che abbiamo visto l’aspetto teorico, occorre addentrarsi un pò di più su quello pratico della questione, perchè in fondo è questo che ci interessa.

Grazie alle ColorMatrix che ci sono state messe a disposizione da Microsoft, è possibile applicare dei filtri pixel per pixel ad una qualsiasi immagine in input ed ottenerne una in output modificata secondo quanto abbiamo specificato nel nostro filtro. L’utilizzo è abbastanza semplice, in quanto occorre “semplicemente” assegnare i valori desiderati proprio ad una matrice, questa:

colormatrix

In pratica lo strumento che ci mette a disposizione .NET è una matrice 4×4 [R;G;B;A] dove A rappresenta la trasparenza del colore che viene moltiplicata ad un vettore colore di 4 elementi [R,G,B,A]. Tuttavia le uniche trasformazioni rappresentabili in 4 dimensioni sono solo quelle lineari, come la rotazione e la scalatura e quindi per garantire il supporto anche alle operazioni non lineari (ad esempio le traslazioni) è stato introdotta una quinta dimensione. In totale si hanno perciò 5 dimensioni totali per la matrice. In particolare ho mostrato nell’immagine quali righe e quali colonne si occupano della trasformazione del colore. In grigio chiaro vediamo quanto riguarda il canale Alpha mentre in grigio scuro vediamo quello che riguarda l’intensità del colore.

La quinta colonna, a parte l’elemento (5,5), è settata a 0 (zero) in quanto non serve a nulla, è stata messa per rendere quadrata la matrice (e quindi velocizzare parecchio i calcoli sottostanti).

A questo punto manca solo da vedere un pò di codice:

private Image FastNullTransform(Image inputImage)
{
Bitmap outputBitmap = new Bitmap(inputImage.Width, inputImage.Height);

ImageAttributes attributes = new ImageAttributes();

ColorMatrix colorMatrix = new ColorMatrix(new float[][] {
new float[] {1, 0, 0, 0, 0},
new float[] {0, 1, 0, 0, 0},
new float[] {0, 0, 1, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
}
);

attributes.SetColorMatrix(colorMatrix);

Graphics outputGraphics = Graphics.FromImage(outputBitmap);
Rectangle rectInput = new Rectangle(0,0,inputImage.Width,inputImage.Height);

outputGraphics.DrawImage(inputImage, rectInput, 0, 0, inputImage.Width, inputImage.Height, GraphicsUnit.Pixel, attributes);
outputGraphics.Dispose();

return outputBitmap;
}

In questo caso particolare abbiamo utilizzato una matrice identità, ovvero una matrice avente come valori tutti zeri a parte che nella diagonale principale (quella che parte dall’elemento 0,0 e va fino al 5,5) dove invece sono presenti degli “uni”. Domani e dopodomani vedremo come utilizzare le ColorMatrix per ottenere effetti molto conosciuti: il GrayScale e il Sepia. A presto! ok emoticon

This entry was posted in Grafica, Linguaggi .Net, Programmazione and tagged , , , , , , , , , , , . Bookmark the permalink.

2 Responses to ColorMatrix – Effetti Pixel per Pixel in C#

  1. sofia says:

    Dennis, sei l’unico che parla di questo …. o forse no…
    Beh grazie a te ho fatto un passetto avanti. Ma non riesco a capire dove scaricare quello schemino che hai con i colori. dici .net e dove vado.
    Sappi che non ci capisco nulla di asp c# e cose varie.
    Con questo sistema pixel per pixel posso
    trasformare le mie fotografie?
    GRAZIE PER L’AIUTO

  2. Denis says:

    sofia:

    Dennis, sei l’unico che parla di questo …. o forse no…
    Beh grazie a te ho fatto un passetto avanti. Ma non riesco a capire dove scaricare quello schemino che hai con i colori. dici .net e dove vado.
    Sappi che non ci capisco nulla di asp c# e cose varie.
    Con questo sistema pixel per pixel posso
    trasformare le mie fotografie?
    GRAZIE PER L’AIUTO

    Ciao Sofia! Guarda secondo me corri un pò troppo, hai già dato un’occhiata alle mie guide per Photoshop e The Gimp? Con questi puoi applicare tutti gli effetti che vuoi sulle tue fotografie, senza la necessità di imparare un linguaggio complesso come il C#… o forse ho capito male io… comunque sia, fammi sapere!

    A presto!

Lascia un Commento

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

*

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>