[英]Compare RGB colors in a pixel and change its original color to the closest one
I need help for my assignment. 我的任务需要帮助。 Basically, this is what I want to do: 基本上,这就是我想要做的:
PictureBox
将图像加载到PictureBox
As the result, I will obtain the image with those three primary colors. 结果,我将获得具有这三种基色的图像。
I have written the code like this: 我写了这样的代码:
Bitmap img = new Bitmap(InputPictureBox.Image);
byte R, G, B;
Color pixelColor;
for (int x = 0; x < img.Width; x++)
{
for (int y = 0; y < img.Height; y++)
{
pixelColor = img.GetPixel(x, y);
R = (byte) Math.Abs(pixelColor.R - 255);
G = (byte) Math.Abs(pixelColor.G - 255);
B = (byte) Math.Abs(pixelColor.B - 255);
if (R < G && R < B)
{
pixelColor = Color.Red;
}
else if (G < R && G < B)
{
pixelColor = Color.Green;
}
else if (B < R && B < G)
{
pixelColor = Color.Blue;
}
}
}
OutputPictureBox.Image = img;
The problem is that the color image then turn to be inverted. 问题是彩色图像然后转向反转。 So, what is wrong in my code? 那么,我的代码有什么问题? I assume that the if
statements don't work, but I don't know why. 我假设if
语句不起作用,但我不知道为什么。 Am I wrong? 我错了吗?
One more question related to my code above, can it actually work by simply calculating the gap of R/G/B value like that OR it absolutely has to be done by using euclidean distance? 还有一个问题与我上面的代码有关,它实际上可以通过简单地计算R / G / B值的差距来实现,或者它必须通过使用欧几里德距离完成吗?
If you don't mind please show me how to fix this or maybe how the code should be written. 如果您不介意,请告诉我如何解决这个问题或者如何编写代码。 I ever read a quite similar question, but the given answer still didn't give me a clue. 我读过一个非常相似的问题,但给出的答案仍然没有给我一些线索。
Your code actually works, although there is a bit of overthinking put into it. 你的代码实际上是有效的,尽管有一些过度的思考。
Try this: 试试这个:
The code has been moved to the Update section at the bottom of the post 代码已移至 帖子底部的“更新” 部分
Result: 结果:
I've removed the overthinking part. 我已经删除了过度思考的部分。
There's no reason (at least from reading your question) why you need to invert the color component values; 没有理由(至少从阅读你的问题)为什么你需要反转颜色分量值;
Simply doing R = pixelColor.R
is enough; 简单地做R = pixelColor.R
就足够了;
And through this you don't have to think of it as "which has the least amount of red", but rather, " if it has the most amount of red, it's red !" 通过这个,您不必将其视为“红色含量最少 ”,而是“ 如果红色含量最多 , 则为 红色 !”
As LightStriker pointed out : You are missing (it is nowhere in your code) the code to set new value back into the image; 正如LightStriker指出的那样 :您缺少(代码中没有任何地方)将新值设置回图像的代码;
img.SetPixel(x, y, pixelColor)
. 这是使用img.SetPixel(x, y, pixelColor)
。 I've added an else
clause to match pixels where no single color component is greater than both others. 我添加了一个else
子句来匹配没有单个颜色分量大于其他颜色分量的像素。
For example, Yellow (255, 255, 0) would not be matched by your rules; 例如,黄色(255,255,0)将不符合您的规则;
Using the version in this answer, it gets replaced by a Black
pixel. 使用此答案中的版本,它将被Black
像素替换。
Update: per the comments below asking for additional clarification. 更新:根据以下评论要求进一步澄清。 Here's how you would add more conditional statements: 以下是添加更多条件语句的方法:
// NEW (start) --------------------------------------------------
Color[] randomizedColors = new Color[] { Color.Red, Color.Green, Color.Blue };
Random randomizer = new Random();
// NEW (end) --------------------------------------------------
Bitmap img = new Bitmap(InputPictureBox.Image);
byte R, G, B;
Color pixelColor;
// NEW (start) --------------------------------------------------
Func<int, Color> ColorRandomizer = (numberOfColors) =>
{
if (numberOfColors > randomizedColors.Length)
{
numberOfColors = randomizedColors.Length;
}
return randomizedColors[randomizer.Next(numberOfColors)];
};
// NEW (end) --------------------------------------------------
for (int x = 0; x < img.Width; x++)
{
for (int y = 0; y < img.Height; y++)
{
pixelColor = img.GetPixel(x, y);
R = pixelColor.R;
G = pixelColor.G;
B = pixelColor.B;
if (R > G && R > B)
{
pixelColor = Color.Red;
}
else if (G > R && G > B)
{
pixelColor = Color.Green;
}
else if (B > R && B > G)
{
pixelColor = Color.Blue;
}
// NEW (start) --------------------------------------------------
else if (pixelColor == Color.Yellow)
{
// 2 = Red or Green
pixelColor = ColorRandomizer(2);
}
else if (pixelColor = Color.FromArgb(152, 152, 152))
{
// 3 = Red, Green, or Blue
pixelColor = ColorRandomizer(3);
}
/* else if (pixelColor = Some_Other_Color)
{
// 3 = Red, Green, or Blue
pixelColor = ColorRandomizer(3);
} */
// NEW (end) --------------------------------------------------
else
{
pixelColor = Color.Black;
}
img.SetPixel(x, y, pixelColor);
}
}
OutputPictureBox.Image = img;
With this updated code, add all colors that should be picked randomly to the randomizedColors
array. 使用此更新的代码,将随机选取的所有颜色添加到randomizedColors
数组中。 Use the lambda function, ColorRandomizer
, to assist in choosing a color randomly; 使用lambda函数ColorRandomizer
来帮助随机选择颜色; keep in mind that this function will randomly pick between the first element and the one specified. 请记住,此函数将在第一个元素和指定的元素之间随机选择。
Following is inverting all the colors. 以下是反转所有颜色。
R = (byte) Math.Abs(pixelColor.R - 255);
G = (byte) Math.Abs(pixelColor.G - 255);
B = (byte) Math.Abs(pixelColor.B - 255);
You can use: 您可以使用:
R = (byte) pixelColor.R;
G = (byte) pixelColor.G;
B = (byte) pixelColor.B;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.