144 lines
4.3 KiB
C#
144 lines
4.3 KiB
C#
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 Thermo.Cam.Utils
|
|
{
|
|
public class ReColorize
|
|
{
|
|
#region Protected Fields
|
|
|
|
protected double maxSca = 5000;
|
|
protected double minSca = -999;
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Public Constructors
|
|
|
|
//public ReColorize(double minValue, double maxValue, double minScale, double maxScale)
|
|
public ReColorize(double minScale, double maxScale)
|
|
{
|
|
minSca = minScale;
|
|
maxSca = maxScale;
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// Calcola colore su scala dato rapporto valore temperatura su min/max
|
|
/// </summary>
|
|
/// <param name="currTemp"></param>
|
|
/// <returns></returns>
|
|
protected Color Rescale(ref double currTemp)
|
|
{
|
|
int R = 0;
|
|
int G = 0;
|
|
int B = 0;
|
|
int ValScal = 0;
|
|
|
|
// 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
|
|
|
|
/// <summary>
|
|
/// Processing ricolorazione
|
|
/// </summary>
|
|
/// <param name="original"></param>
|
|
/// <param name="tempVal"></param>
|
|
/// <returns></returns>
|
|
public Bitmap process(Bitmap original, double[] tempVal)
|
|
{
|
|
/*---------------------------------------------
|
|
// 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);
|
|
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)
|
|
{
|
|
var newCol = Rescale(ref tempVal[x / bytesPerPixel + original.Width * y]);
|
|
pixels[currentLine + x] = (byte)newCol.B;
|
|
pixels[currentLine + x + 1] = (byte)newCol.G;
|
|
pixels[currentLine + x + 2] = (byte)newCol.R;
|
|
}
|
|
}
|
|
|
|
// copy modified bytes back
|
|
Marshal.Copy(pixels, 0, ptrFirstPixel, pixels.Length);
|
|
imgColor.UnlockBits(bitmapData);
|
|
|
|
return imgColor;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
} |