Reputation: 43
I have written some c# code converting my rgb image to grayscale and I would like to convert the grayscale to only 2 colors, black and while. Can you help?
Code:-
Bitmap bmp = new Bitmap(file);
int width = bmp.Width;
int height = bmp.Height;
int[] arr = new int[225];
int i = 0;
Color p;
//Grayscale
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
p = bmp.GetPixel(x,y);
int a = p.A;
int r = p.R;
int g = p.G;
int b = p.B;
int avg = (r+g+b)/3;
bmp.SetPixel(x, y, Color.FromArgb(a, avg ,avg, avg));
}
}
pictureBox2.Image = bmp;
Upvotes: 3
Views: 13102
Reputation: 20464
You should stop using GetPixel
method on any scenario.
I'm an VB.Net guy, I've write this approach which you can convert the image to black and white.
First I apply the gray matrix then with the SetThreshold
method I set the threshold that separates black from white.
''' <summary>
''' Transforms an image to black and white.
''' </summary>
''' <param name="img">The image.</param>
''' <returns>The black and white image.</returns>
Public Shared Function GetBlackAndWhiteImage(ByVal img As Image) As Image
Dim bmp As Bitmap = New Bitmap(img.Width, img.Height)
Dim grayMatrix As New System.Drawing.Imaging.ColorMatrix(
{
New Single() {0.299F, 0.299F, 0.299F, 0, 0},
New Single() {0.587F, 0.587F, 0.587F, 0, 0},
New Single() {0.114F, 0.114F, 0.114F, 0, 0},
New Single() {0, 0, 0, 1, 0},
New Single() {0, 0, 0, 0, 1}
})
Using g As Graphics = Graphics.FromImage(bmp)
Using ia As System.Drawing.Imaging.ImageAttributes = New System.Drawing.Imaging.ImageAttributes()
ia.SetColorMatrix(grayMatrix)
ia.SetThreshold(0.5)
g.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height,
GraphicsUnit.Pixel, ia)
End Using
End Using
Return bmp
End Function
Online translation to C#:
/// <summary>
/// Transforms an image to black and white.
/// </summary>
/// <param name="img">The image.</param>
/// <returns>The black and white image.</returns>
public static Image GetBlackAndWhiteImage(Image img)
{
Bitmap bmp = new Bitmap(img.Width, img.Height);
System.Drawing.Imaging.ColorMatrix grayMatrix = new ColorMatrix(
new float[][] {
new float[] { 0.299f, 0.299f, 0.299f, 0, 0 },
new float[] { 0.587f, 0.587f, 0.587f, 0, 0 },
new float[] { 0.114f, 0.114f, 0.114f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1}
}););
using (Graphics g = Graphics.FromImage(bmp)) {
using (System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes()) {
ia.SetColorMatrix(grayMatrix);
ia.SetThreshold(0.5);
g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia);
}
}
return bmp;
}
//=======================================================
//Service provided by Telerik (www.telerik.com)
//=======================================================
Upvotes: 6
Reputation: 2019
I've changed your code a little. So light gray pixels become pure white and dark gray pixels become pure black.
Bitmap bmp = new Bitmap(file);
int width = bmp.Width;
int height = bmp.Height;
int[] arr = new int[225];
int i = 0;
Color p;
//Grayscale
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
p = bmp.GetPixel(x,y);
int a = p.A;
int r = p.R;
int g = p.G;
int b = p.B;
int avg = (r+g+b)/3;
avg = avg < 128 ? 0 : 255; // Converting gray pixels to either pure black or pure white
bmp.SetPixel(x, y, Color.FromArgb(a, avg ,avg, avg));
}
}
pictureBox2.Image = bmp;
Upvotes: 4