martedì 28 ottobre 2025

C# applicare ad una foto o immagine esistente l'effetto infrared

 

C# effetto infrared

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: