JAMES
asked on
Convert bitmap from 24 bit to monochrome.
Hi,
Is there an "easy" way of converting a 24 bit bitmap to a monochrome image (the same as "save as - monochrome" in mspaint for example).
Thanks.
James.
Is there an "easy" way of converting a 24 bit bitmap to a monochrome image (the same as "save as - monochrome" in mspaint for example).
Thanks.
James.
http://www.codeproject.com/cs/media/csharpgraphicfilters11.asp
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Cool - many thanks.
James.
James.
Correction in BitsToBitmapMonochrome function:
if (data.Stride == width * 3)
should be
if (data.Stride == width)
if (data.Stride == width * 3)
should be
if (data.Stride == width)
ASKER
Thanks.
ASKER
Alex,
Not sure if you still see any messages posted here now this one is closed but after using the above method I have discovered the PixelFormat of captured bitmaps is PixelFormat.Format32bppArg b.
Should I be able to use the same routine anyway (after altering the initial check which returns null) ?
Thanks.
James.
Not sure if you still see any messages posted here now this one is closed but after using the above method I have discovered the PixelFormat of captured bitmaps is PixelFormat.Format32bppArg
Should I be able to use the same routine anyway (after altering the initial check which returns null) ?
Thanks.
James.
You can create RGB24 bitmap, explicitly providing PixelFormat parameter to Bitmap constructor, for capturing code. Try this, if it doesn't work, I will post code for 32 bpp bitmap.
ASKER
I *think* it works but the result looks different to when I "save as" to Monochrome in MS Paint.
Changed without test, hope it will work:
Bitmap ConvertRGB32ToMonochrome(B itmap source)
{
if ( source.PixelFormat != PixelFormat.Format32bppRgb )
{
return null;
}
Byte[] colorBytes = BitmapToBytesRGB32(source) ;
if ( colorBytes == null )
{
return null;
}
Byte[] monoBytes = new Byte[source.Width * source.Height];
int j = 0;
for ( int i = 0; i < source.Width * source.Height; i++ )
{
monoBytes[i] = (Byte)(0.3f * (float)colorBytes[j + 2] + 0.59f * (float)colorBytes[j + 1] + 0.11f * (float)colorBytes[j]);
j += 4;
}
return BitsToBitmapMonochrome(mon oBytes, source.Width, source.Height);
}
// Create monochrome bitmap from Byte array
Bitmap BitsToBitmapMonochrome(Byt e[] bytes, int width, int height)
{
if (bytes.GetLength(0) < width * height)
{
return null;
}
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppInde xed);
int i;
bmp.Palette = GetGrayScalePalette();
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.WriteOnly, bmp.PixelFormat);
if (data.Stride == width)
{
Marshal.Copy(bytes, 0, data.Scan0, width * height);
}
else
{
for (i = 0; i < bmp.Height; i++)
{
IntPtr p = new IntPtr(data.Scan0.ToInt32( ) + data.Stride * i);
Marshal.Copy(bytes, i * bmp.Width, p, bmp.Width);
}
}
bmp.UnlockBits(data);
return bmp;
}
// Create Byte array from RGB32 bitmap
Byte[] BitmapToBytesRGB32(Bitmap bmp)
{
if ( bmp.PixelFormat != PixelFormat.Format32bppRgb )
{
return null;
}
int i;
int length = bmp.Width * bmp.Height * 4;
Byte[] bytes = new Byte[length];
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadOnly, bmp.PixelFormat);
if (data.Stride == bmp.Width * 4)
{
Marshal.Copy(data.Scan0, bytes, 0, length);
}
else
{
for ( i = 0; i < bmp.Height; i++ )
{
IntPtr p = new IntPtr(data.Scan0.ToInt32( ) + data.Stride * i);
Marshal.Copy(p, bytes, i * bmp.Width * 4, bmp.Width * 4);
}
}
bmp.UnlockBits(data);
return bytes;
}
ColorPalette GetGrayScalePalette()
{
Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppInde xed);
ColorPalette monoPalette = bmp.Palette;
Color[] entries = monoPalette.Entries;
for ( int i = 0; i < 256; i++ )
{
entries[i] = Color.FromArgb(i, i, i);
}
return monoPalette;
}
}
Bitmap ConvertRGB32ToMonochrome(B
{
if ( source.PixelFormat != PixelFormat.Format32bppRgb
{
return null;
}
Byte[] colorBytes = BitmapToBytesRGB32(source)
if ( colorBytes == null )
{
return null;
}
Byte[] monoBytes = new Byte[source.Width * source.Height];
int j = 0;
for ( int i = 0; i < source.Width * source.Height; i++ )
{
monoBytes[i] = (Byte)(0.3f * (float)colorBytes[j + 2] + 0.59f * (float)colorBytes[j + 1] + 0.11f * (float)colorBytes[j]);
j += 4;
}
return BitsToBitmapMonochrome(mon
}
// Create monochrome bitmap from Byte array
Bitmap BitsToBitmapMonochrome(Byt
{
if (bytes.GetLength(0) < width * height)
{
return null;
}
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppInde
int i;
bmp.Palette = GetGrayScalePalette();
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.WriteOnly, bmp.PixelFormat);
if (data.Stride == width)
{
Marshal.Copy(bytes, 0, data.Scan0, width * height);
}
else
{
for (i = 0; i < bmp.Height; i++)
{
IntPtr p = new IntPtr(data.Scan0.ToInt32(
Marshal.Copy(bytes, i * bmp.Width, p, bmp.Width);
}
}
bmp.UnlockBits(data);
return bmp;
}
// Create Byte array from RGB32 bitmap
Byte[] BitmapToBytesRGB32(Bitmap bmp)
{
if ( bmp.PixelFormat != PixelFormat.Format32bppRgb
{
return null;
}
int i;
int length = bmp.Width * bmp.Height * 4;
Byte[] bytes = new Byte[length];
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadOnly, bmp.PixelFormat);
if (data.Stride == bmp.Width * 4)
{
Marshal.Copy(data.Scan0, bytes, 0, length);
}
else
{
for ( i = 0; i < bmp.Height; i++ )
{
IntPtr p = new IntPtr(data.Scan0.ToInt32(
Marshal.Copy(p, bytes, i * bmp.Width * 4, bmp.Width * 4);
}
}
bmp.UnlockBits(data);
return bytes;
}
ColorPalette GetGrayScalePalette()
{
Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppInde
ColorPalette monoPalette = bmp.Palette;
Color[] entries = monoPalette.Entries;
for ( int i = 0; i < 256; i++ )
{
entries[i] = Color.FromArgb(i, i, i);
}
return monoPalette;
}
}
ASKER
Does it matter you are using Format32bppRBG but my pixelformat is Format32bppArgb ?
Sorry to possibly be asking dumb questions but this level of image manipulation is new to me.
Many thanks.
james.
Sorry to possibly be asking dumb questions but this level of image manipulation is new to me.
Many thanks.
james.
It is just result of my "online" correction, Format32bppArgb is correct.
But i want to change the bitmap image to 1 Bpp Monochrome. as like in MS paint