Files
cms_thermo_active/ThermoCamUtils/ReColorize.cs
T
2021-02-12 19:33:34 +01:00

169 lines
5.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 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
/// <summary>
/// Calcola colore su scala dato rapporto valore B/N su min/max
/// </summary>
/// <param name="ValOrig"></param>
/// <returns></returns>
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
}
}