using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; namespace ThermoCamUtils { public class ReColorize { #region Protected Fields protected double delta = 0; protected double maxSca = 5000; protected double maxVal = 5000; protected double minSca = -999; protected double minVal = -999; #endregion Protected Fields #region Public Constructors public ReColorize(double minValue, double maxValue, double minScale, double maxScale) { minVal = minValue; maxVal = maxValue; minSca = minScale; maxSca = maxScale; delta = minVal - minSca; } #endregion Public Constructors #region Protected Methods /// /// Calcola colore su scala dato rapporto valore B/N su min/max /// /// /// protected Color Rescale(ref int ValRGB) { int R = 0; int G = 0; int B = 0; int ValScal = 0; // calcolo retta interpolazione per il valore in gradi...Y = M * X + DELTA double M = (maxVal - minVal) / 255; double currTemp = M * ValRGB + delta; // ora calcolo valore scalare ValScal = (int)(255 * (currTemp - minSca) / (maxSca - minSca)); if (ValScal < 0) { R = 0; G = 0; B = 0; } else if (ValScal <= 51) { R = 0; G = 0; B = (int)(ValScal * 5); } else if (ValScal <= 102) { R = (int)((ValScal - 51) * 5); G = 0; B = 255; } else if (ValScal <= 153) { R = 255; G = 0; B = (int)(255 - ((ValScal - 102) * 5)); } else if (ValScal <= 204) { R = 255; G = (int)((ValScal - 153) * 5); B = 0; } else if (ValScal <= 255) { R = 255; G = 255; B = (int)((ValScal - 204) * 5); } else { R = 255; G = 255; B = 255; } return Color.FromArgb(R, G, B); } #endregion Protected Methods #region Public Methods public Bitmap process(Bitmap original, bool doFast) { /*--------------------------------------------- // indicazioni x ottimizzare da qui: // http://csharpexamples.com/tag/parallel-bitmap-processing/ -----------------------------------------------*/ Bitmap imgColor = original.Clone(new Rectangle(0, 0, original.Width, original.Height), original.PixelFormat); int currVal = 0; if (doFast) { BitmapData bitmapData = imgColor.LockBits(new Rectangle(0, 0, imgColor.Width, imgColor.Height), ImageLockMode.ReadWrite, imgColor.PixelFormat); int bytesPerPixel = Bitmap.GetPixelFormatSize(imgColor.PixelFormat) / 8; int byteCount = bitmapData.Stride * imgColor.Height; byte[] pixels = new byte[byteCount]; IntPtr ptrFirstPixel = bitmapData.Scan0; Marshal.Copy(ptrFirstPixel, pixels, 0, pixels.Length); int heightInPixels = bitmapData.Height; int widthInBytes = bitmapData.Width * bytesPerPixel; for (int y = 0; y < heightInPixels; y++) { int currentLine = y * bitmapData.Stride; for (int x = 0; x < widthInBytes; x = x + bytesPerPixel) { // prendo il rosso int oldRed = pixels[currentLine + x + 0]; currVal = pixels[currentLine + x + 2]; var newCol = Rescale(ref currVal); pixels[currentLine + x] = (byte)newCol.B; pixels[currentLine + x + 1] = (byte)newCol.G; pixels[currentLine + x + 2] = (byte)newCol.R; //currVal = original.GetPixel(x, y).R; //imgColor.SetPixel(x, y, Rescale(ref currVal)); } } // copy modified bytes back Marshal.Copy(pixels, 0, ptrFirstPixel, pixels.Length); imgColor.UnlockBits(bitmapData); } else { // recupero matrice di punti con valore RGB for (int x = 0; x < original.Width; x++) { for (int y = 0; y < original.Height; y++) { // esecuo ricalcolo currVal = original.GetPixel(x, y).R; imgColor.SetPixel(x, y, Rescale(ref currVal)); } } } return imgColor; } #endregion Public Methods } }