Reputation: 33
I need help for my assignment. Basically, this is what I want to do:
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.
Upvotes: 3
Views: 6140
Reputation: 8749
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;
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:
// 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. 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.
Upvotes: 4
Reputation: 2085
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;
Upvotes: 0