I need help for my assignment. Basically, this is what I want to do:
- Load an image to a
PictureBox
- Calculate the difference between 255 (the maximum value) and the R value in each pixel, and the difference between 255 and G value, and also for B value
- From the calculation above, the least absolute value will indicate that the pixel's color is closer to that color (ex: (255-R value) has the smallest absolute value, so the pixel is closer to that color)
- Change the pixel color to the closer color (in example above, it means change it to Red)
- Display the result in the output 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. 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?
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.
Best Answer
Your code actually works, although there is a bit of overthinking put into it.
Try this:
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;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;
img.SetPixel(x, y, pixelColor)
.I've added an
else
clause to match pixels where no single color component is greater than both others.For example, Yellow (255, 255, 0) would not be matched by your rules;
Using the version in this answer, it gets replaced by a
Black
pixel.Update: per the comments below asking for additional clarification. Here's how you would add more conditional statements:
With this updated code, add all colors that should be picked randomly to the
randomizedColors
array. Use the lambda function,ColorRandomizer
, to assist in choosing a color randomly; keep in mind that this function will randomly pick between the first element and the one specified.