In questo esempio di codice nel linguaggio di programmazione C#, vedremo come applicare ad una foto o immagine esistente l'effetto infrared, utilizzando presenti nello spazio dei nomi di "System.Drawing" per la versione 9 di del Framework .Net.
Senza utilizzare terze librerie, vedremo come da un progetto di tipo "Windows Application", applicheremo tale effetto, creando una nuova immagine da quella esistente.
Il risultato sarà come mostrato nell'immagine riportata qui in alto.
Aggiungiamo lo spazio dei nomi per la gestione della grafica, in alto, sopra ad ogni dichiarazione inseriamo il seguente spazio dei nomi.
C#
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
Nell forma, in una qualunque parte, scriviamo la seguente funzione, che data un'immagine a colori, applicherà l'effetto creando una nuova immagine.
Di seguito si riporta la funzione per creare una nuova immagine con effetto infrared.
C#
private Bitmap EffettoInfrared(Bitmap sourceImage)
{
// Crea una nuova bitmap per applicare l'effetto
Bitmap infraredImage = new Bitmap(sourceImage.Width, sourceImage.Height);
// Blocca la bitmap sorgente per un
accesso più veloce ai pixel
BitmapData sourceData = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.Width,
sourceImage.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
// Blocca la bitmap di destinazione
BitmapData infraredData = infraredImage.LockBits(new Rectangle(0, 0, infraredImage.Width,
infraredImage.Height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
// Ottieni puntatori ai dati dei pixel
IntPtr sourcePtr = sourceData.Scan0;
IntPtr infraredPtr = infraredData.Scan0;
// Numero di byte per riga (inclusi
eventuali padding)
int
bytesPerScanLine = sourceData.Stride;
int totalBytes = bytesPerScanLine * sourceImage.Height;
// Crea array di byte per contenere i
dati dei pixel
byte[] sourcePixels = new byte[totalBytes];
byte[] infraredPixels = new byte[totalBytes];
// Copia i dati dei pixel dalla
sorgente
System.Runtime.InteropServices.Marshal.Copy(sourcePtr, sourcePixels, 0, totalBytes);
// Itera su ogni pixel
for (int y = 0; y
< sourceImage.Height; y++)
{
for (int x = 0; x
< sourceImage.Width; x++)
{
// Indice del pixel corrente (formato BGRA/ARGB)
int index = (y * bytesPerScanLine) + (x * 4);
//
Estrai i canali di colore (Blue, Green, Red, Alpha)
byte blue = sourcePixels[index];
byte green = sourcePixels[index + 1];
byte red = sourcePixels[index + 2];
byte alpha = sourcePixels[index + 3];
//
Calcola una sorta di luminosità o valore medio
// Usiamo una media ponderata per dare più peso al
verde (spesso più sensibile)
double average = (blue * 0.2 + green * 0.6 + red * 0.2) / 255.0;
// Mappa
'average' a nuovi colori
// Se 'average' è alto (caldo), tende al
giallo/bianco
// Se 'average' è basso (freddo), tende al blu/nero
byte newRed, newGreen, newBlue;
if (average > 0.7)
{
// Caldo: Tende al bianco/giallo
newRed = (byte)Math.Min(255, red
+ (average - 0.7) * 255 * 1.5);
newGreen = (byte)Math.Min(255, green + (average - 0.7) * 255 * 1.5);
newBlue = (byte)Math.Max(0, blue - (average - 0.7) * 255 * 0.5);
}
else if (average < 0.3)
{
// Freddo: Tende al blu/nero
newRed = (byte)Math.Max(0, red - (0.3 - average) * 255 * 0.5);
newGreen = (byte)Math.Max(0, green - (0.3 - average) * 255 * 0.5);
newBlue = (byte)Math.Min(255, blue + (0.3 - average) * 255 * 1.5);
}
else
{
// Intermedio: Mantiene un po' dei colori originali
con una leggera dominante
newRed = red;
newGreen = green;
newBlue = blue;
}
//I valori devono rimanere entro 0-255
newRed = Math.Max((byte)0, Math.Min((byte)255,
newRed));
newGreen = Math.Max((byte)0, Math.Min((byte)255, newGreen));
newBlue = Math.Max((byte)0, Math.Min((byte)255, newBlue));
//
Assegna i nuovi valori dei pixel (BGRA)
infraredPixels[index]
= newBlue;
infraredPixels[index + 1] = newGreen;
infraredPixels[index + 2] = newRed;
infraredPixels[index + 3] = alpha; // Alpha
rimane invariato
}
}
// Copia i pixel modificati nella
bitmap di destinazione
System.Runtime.InteropServices.Marshal.Copy(infraredPixels, 0, infraredPtr,
totalBytes);
// Sblocca le bitmap
sourceImage.UnlockBits(sourceData);
infraredImage.UnlockBits(infraredData);
return infraredImage;
}
Di seguito il codice da inserire nell'evento click di un pulsante, per richiamare la funzione e creare la nuova immagine con tale effetto.
C#
private void BtnEffettoInfared_Click(object sender, EventArgs e)
{
string immagineOriginale = "C:\\varie\\faro.jpg";
string immagineNuovaInfared = "C:\\varie\\faroInfrared.jpg";
try
{
using (Bitmap
originalBitmap = new Bitmap(immagineOriginale))
{
Bitmap infraredBitmap = EffettoInfrared(originalBitmap);
infraredBitmap.Save(immagineNuovaInfared);
MessageBox.Show("Immagine con effetto Infrared creata con
successo");
}
}
catch (Exception ex)
{
MessageBox.Show($"Errore
nell'applicazione dell\'effetto infrarosso: {ex.Message}");
}
}

Nessun commento:
Posta un commento