Faster way to create True B/W Image
-
I am using the following code and it does create a B/W image as desired but it seems to be very slow. IS there a better way to do this? Thanks in advance.
Dim bm As New Bitmap(picCanvas.Image) Dim X As Integer Dim Y As Integer Dim clr As Integer Dim r As Integer Dim g As Integer Dim b As Integer For X = 0 To bm.Width - 1 For Y = 0 To bm.Height - 1 clr = (CInt(bm.GetPixel(X, Y).R) + \_ bm.GetPixel(X, Y).G + \_ bm.GetPixel(X, Y).B) \\ 3 bm.SetPixel(X, Y, Color.FromArgb(clr, clr, clr)) r = 255 - bm.GetPixel(X, Y).R g = 255 - bm.GetPixel(X, Y).G b = 255 - bm.GetPixel(X, Y).B bm.SetPixel(X, Y, Color.FromArgb(r, g, b)) Next Y Next X picCanvas.Image = bm
-
I am using the following code and it does create a B/W image as desired but it seems to be very slow. IS there a better way to do this? Thanks in advance.
Dim bm As New Bitmap(picCanvas.Image) Dim X As Integer Dim Y As Integer Dim clr As Integer Dim r As Integer Dim g As Integer Dim b As Integer For X = 0 To bm.Width - 1 For Y = 0 To bm.Height - 1 clr = (CInt(bm.GetPixel(X, Y).R) + \_ bm.GetPixel(X, Y).G + \_ bm.GetPixel(X, Y).B) \\ 3 bm.SetPixel(X, Y, Color.FromArgb(clr, clr, clr)) r = 255 - bm.GetPixel(X, Y).R g = 255 - bm.GetPixel(X, Y).G b = 255 - bm.GetPixel(X, Y).B bm.SetPixel(X, Y, Color.FromArgb(r, g, b)) Next Y Next X picCanvas.Image = bm
You call bm.GetPixel 6 times with exactly the same X and Y values - do it once only and store the result. Next, you calculate the average of RGB values, set that to the pixel, and call again that GetPixel method, just to substract its value from 255. Do you think the RGB values are different here from each other? Why don't you just substract the average from 255 before the first SetPixel call (and throw away the second half of the method)?
-
I am using the following code and it does create a B/W image as desired but it seems to be very slow. IS there a better way to do this? Thanks in advance.
Dim bm As New Bitmap(picCanvas.Image) Dim X As Integer Dim Y As Integer Dim clr As Integer Dim r As Integer Dim g As Integer Dim b As Integer For X = 0 To bm.Width - 1 For Y = 0 To bm.Height - 1 clr = (CInt(bm.GetPixel(X, Y).R) + \_ bm.GetPixel(X, Y).G + \_ bm.GetPixel(X, Y).B) \\ 3 bm.SetPixel(X, Y, Color.FromArgb(clr, clr, clr)) r = 255 - bm.GetPixel(X, Y).R g = 255 - bm.GetPixel(X, Y).G b = 255 - bm.GetPixel(X, Y).B bm.SetPixel(X, Y, Color.FromArgb(r, g, b)) Next Y Next X picCanvas.Image = bm
There are several solutions at: http://tech.pro/tutorial/660/csharp-tutorial-convert-a-color-image-to-grayscale[^] They're in C#, but they should be fairly easy to convert. The simplest method is probably to use a
ColorMatrix
:public static Bitmap MakeGrayscale(Bitmap original)
{
Bitmap newBitmap = new Bitmap(original.Width, original.Height);using (Graphics g = Graphics.FromImage(newBitmap))
{
ColorMatrix colorMatrix = new ColorMatrix(
new float[][]
{
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});ImageAttributes attributes = new ImageAttributes(); attributes.SetColorMatrix(colorMatrix); g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height), 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
}
return newBitmap;
}Michael Combs posted a good article on the
ColorMatrix
back in 2003, which includes VB.NET samples: ColorMatrix Basics - Simple Image Color Adjustment[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
You call bm.GetPixel 6 times with exactly the same X and Y values - do it once only and store the result. Next, you calculate the average of RGB values, set that to the pixel, and call again that GetPixel method, just to substract its value from 255. Do you think the RGB values are different here from each other? Why don't you just substract the average from 255 before the first SetPixel call (and throw away the second half of the method)?
-
There are several solutions at: http://tech.pro/tutorial/660/csharp-tutorial-convert-a-color-image-to-grayscale[^] They're in C#, but they should be fairly easy to convert. The simplest method is probably to use a
ColorMatrix
:public static Bitmap MakeGrayscale(Bitmap original)
{
Bitmap newBitmap = new Bitmap(original.Width, original.Height);using (Graphics g = Graphics.FromImage(newBitmap))
{
ColorMatrix colorMatrix = new ColorMatrix(
new float[][]
{
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});ImageAttributes attributes = new ImageAttributes(); attributes.SetColorMatrix(colorMatrix); g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height), 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
}
return newBitmap;
}Michael Combs posted a good article on the
ColorMatrix
back in 2003, which includes VB.NET samples: ColorMatrix Basics - Simple Image Color Adjustment[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer