Попытка использовать цветовые матрицы для динамического перекрашивания изображений с высоким разрешением во время выполнC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Попытка использовать цветовые матрицы для динамического перекрашивания изображений с высоким разрешением во время выполн

Сообщение Anonymous »

Я пытаюсь создать класс, который сможет перекрашивать изображения с высоким разрешением в реальном времени с минимальной задержкой. Я остановился на использовании цветовых матриц, потому что рекомендуемый метод попиксельной замены цвета с использованием справочных таблиц был бы ограничительным и непомерно вычислительным. Однако, насколько я могу судить, никто этого раньше не делал (во что мне крайне трудно поверить). Я собрал воедино свои предположения, используя различные ресурсы, наиболее полезными из которых были:
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]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»