https://graficaobscura.com/matrix/index.html
https. ://learn.microsoft.com/en-us/windows/win32/direct2d/hue-rotate?redirectedfrom=MSDN
Поворот оттенка в C#
Проблема в том, что код, который я придумал, работает не совсем правильно, и, к сожалению, я не могу сказать, просто взглянув на цвет, что пошло не так, что делает отладку практически невозможной.
Вот что я сейчас делаю есть для моего класса по перекрашиванию:
Код: Выделить всё
public class Recolorer
{
const float LumR = 0.2126f;
const float LumG = 0.7152f;
const float LumB = 0.0722f;
public bool UseSat = true;
public bool UseLum = false;
public bool UseBri = true;
public Bitmap Recolor(Bitmap bm, Color BaseColor, Color NewColor)
{
float r = 1;
float d = 0;
d = BrightnessDelta(BaseColor, NewColor);
float[][] H = HueMatrix(NewColor, BaseColor.GetHue());
float[][] S = SaturationMatrix(NewColor);
float[][] L = LuminosityMatrix();
float[][] B = LightnessMatrix(r, d);
float[][] T = H;
if (UseSat)
T = Multiply(S, T);
if (UseLum)
T = Multiply(L, T);
if (UseBri)
T = Multiply(B, T);
ColorMatrix cm = new ColorMatrix(T);
ImageAttributes ia = new ImageAttributes();
ia.SetColorMatrix(cm);
Rectangle rect = new Rectangle(0, 0, bm.Width, bm.Height);
Bitmap temp = new Bitmap(bm.Width, bm.Height);
Graphics g = Graphics.FromImage(temp);
g.DrawImage(bm, rect, 0, 0, bm.Width, bm.Height, GraphicsUnit.Pixel, ia);
return temp;
}
public float[][] LuminosityMatrix(float B = 1f)
{
return new float[][] {
new float[] {LumR * B, LumR * B, LumR * B, 0, 0},
new float[] {LumG * B, LumG * B, LumG * B, 0, 0},
new float[] {LumB * B, LumB * B, LumB * B, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
};
}
public float[][] SaturationMatrix(Color c)
{
float s = c.GetSaturation();
float sr = (1f - s) * LumR;
float sg = (1f - s) * LumG;
float sb = (1f - s) * LumB;
return new float[][] {
new float[] {sr+s, sr, sr, 0, 0},
new float[] {sg, sg+s, sg, 0, 0},
new float[] {sb, sb, sb+s, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
};
}
public float[][] HueMatrix(Color c, float x = 0)
{
float angle = c.GetHue() - x;
angle /= 180f;
float cos = (float)Math.Cos(angle * Math.PI);
float sin = (float)Math.Sin(angle * Math.PI);
float A00 = LumR + (1 - LumR) * cos - LumR * sin;
float A01 = LumR - LumR * cos + 0.413f * sin;
float A02 = LumR - LumR * cos - (1 - LumR) * sin;
float A10 = LumG - LumG * cos - LumG * sin;
float A11 = LumG + (1 - LumG) * cos + 0.140f * sin;
float A12 = LumG - LumG * cos + LumG * sin;
float A20 = LumB - LumB * cos + (1 - LumB) * sin;
float A21 = LumB - LumB * cos - 0.283f * sin;
float A22 = LumB + (1 - LumB) * cos + LumB * sin;
return new float[][] {
new float[] { A00, A01, A02, 0, 0 },
new float[] { A10, A11, A12, 0, 0 },
new float[] { A20, A21, A22, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1 }
};
}
public float GetBrightness(Color c)
{
return (((float)c.R * LumR / 255f) + ((float)c.G * LumG / 255f) + ((float)c.B * LumB / 255f));
}
public float BrightnessRatio(Color From, Color To)
{
return (GetBrightness(To) / GetBrightness(From));
}
public float BrightnessDelta(Color From, Color To)
{
return ((GetBrightness(To) - GetBrightness(From)) / 2f);
}
public float[][] LightnessMatrix(float f = 1, float l = 0)
{
return new float[][] {
new float[] { f, 0, 0, 0, 0 },
new float[] { 0, f, 0, 0, 0 },
new float[] { 0, 0, f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { l, l, l, 0, 1 }
};
}
public float[][] Multiply(float[][] A, float[][] B)
{
const int size = 5;
float temp = 0;
float[][] C = new float[size][];
for (int sigh = 0; sigh
Подробнее здесь: [url]https://stackoverflow.com/questions/78641394/attempting-to-use-color-matrices-to-dynamically-re-color-high-res-images-at-runt[/url]