I'm trying to build a function to convert a color image to monochrome. There's a lot of confusion around terminology, but I'm talking about true black-and-white, where we only have 2 colors: black and white - no grays.
Here is an example of what I'm trying to achieve:
I also wanted a way to control the "threshold" of the conversion (i.e. how "bright" does a pixel have to be to produce a white pixel).
Here is what I have right now.
private Bitmap bitmap2Monochrome(Bitmap srcImg, int brightness)
{
Bitmap monoImg = new Bitmap(srcImg.Width, srcImg.Height);
// Loop through all the pixels in the image
for (int y = 0; y < srcImg.Height; y++)
{
for (int x = 0; x < srcImg.Width; x++)
{
// Get pixel color
Color existingColor = srcImg.GetPixel(x, y);
// Average R, G, and B to determine "brightness" of this pixel
int gray = (int)((existingColor.R + existingColor.G + existingColor.G) / 3);
// If the "brightness" is greater than the threshold, this is a white pixel
int color = 0;
if (gray > brightness)
{
color = 255;
}
// Update the output image
Color newColor = Color.FromArgb(color, color, color);
monoImg.SetPixel(x, y, newColor);
}
}
return monoImg;
}
This method works exactly the way I want, but it is (understandably) very slow. This is due to the fact that the GetPixel()
and SetPixel()
functions are very slow.
I would love to use a ColorMatrix
because they are so fast, but I'm not very good at matrices, and I can't seem to come up with a matrix that would achieve this result.
Here's an example of how the logic works:
(200, 150, 250)
(200, 200, 200)
200
200 > threshold
255
(255, 255, 255)
Is there any way I could achieve this sort of functionality using a ColorMatrix
?
I'm also open to other ideas!
Consider using an identity ColorMatrix
with the fifth row of
{ -threshold, -threshold, -threshold, 0, 1 }
This will allow you to shift all colors below your threshold to 0
Then you could use a second ColorMatrix
to multiply all RGB so they are larger than 1.0d. That would create the effect you want(assuming the implementation of ColorMatrix prevents negative values and larger values than 1.0d
)