Reputation: 16461
I have a 8 bit bitmap color image. when i do a
Color pixelcolor = b.GetPixel(j,i);
Console.Write(pixelcolor.ToString() + " " );
I get
Color [A=255, R=255, G=255, B=255]
I need to get only the 8 bit value. not 24 bit seperate values for R,G,B ,A.
Upvotes: 3
Views: 3177
Reputation: 13085
There is no way to do this using the Bitmap
class directly. However, you can use the LockBits
method to access the pixels directly.
Using unsafe code: (remember to enable unsafe code in your project first)
public static unsafe Byte GetIndexedPixel(Bitmap b, Int32 x, Int32 y)
{
if (b.PixelFormat != PixelFormat.Format8bppIndexed) throw new ArgumentException("Image is not in 8 bit per pixel indexed format!");
if (x < 0 || x >= b.Width) throw new ArgumentOutOfRangeException("x", string.Format("x should be in 0-{0}", b.Width));
if (y < 0 || y >= b.Height) throw new ArgumentOutOfRangeException("y", string.Format("y should be in 0-{0}", b.Height));
BitmapData data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, b.PixelFormat);
try
{
Byte* scan0 = (Byte*)data.Scan0;
return scan0[x + y * data.Stride];
}
finally
{
if (data != null) b.UnlockBits(data);
}
}
The safe alternative, using Marshal.Copy
:
public static Byte GetIndexedPixel(Bitmap b, Int32 x, Int32 y)
{
if (b.PixelFormat != PixelFormat.Format8bppIndexed) throw new ArgumentException("Image is not in 8 bit per pixel indexed format!");
if (x < 0 || x >= b.Width) throw new ArgumentOutOfRangeException("x", string.Format("x should be in 0-{0}", b.Width));
if (y < 0 || y >= b.Height) throw new ArgumentOutOfRangeException("y", string.Format("y should be in 0-{0}", b.Height));
BitmapData data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, b.PixelFormat);
try
{
Byte[] pixel = new Byte[1];
Marshal.Copy(new IntPtr(data.Scan0.ToInt64() + x + y * data.Stride), pixel, 0, 1);
return pixel[0];
}
finally
{
if (data != null) b.UnlockBits(data);
}
}
Upvotes: 5
Reputation: 5294
If you don't want to use LockBits, you can do this:
Warning: This method only works if the palette does not have duplicated values and if it is not changed by another thread after pixelRGB is set.
/// <summary>
/// Gets the pixel value in bytes. Uses Bitmap GetPixel method.
/// </summary>
/// <param name="bmp">Bitmap</param>
/// <param name="location">Pixel location</param>
/// <returns>Pixel value</returns>
public static byte Get8bppImagePixel(Bitmap bmp, Point location)
{
Color pixelRGB = bmp.GetPixel(location.X, location.Y);
int pixel8bpp = Array.IndexOf(bmp.Palette.Entries, pixelRGB);
return (byte)pixel8bpp;
}
Upvotes: -1
Reputation: 700730
The methods in the Bitmap
class doesn't let you get the palette index directly.
You can get the palette for the image using the Palette
property, and look for the color there, but that's a bit of a workaround.
To get the palette index directly, you would use the LockBits
method to get access to the image data directly. You would either have to use marshalling to copy the data into an array, or use pointers in unsafe mode to access it.
The A
property in a Color
value is the Alpha component. It can have the value 0 to 255, where 0 is fully transparent and 255 is fully solid.
Upvotes: 1
Reputation: 62265
The values you want are actually R
, G
and B
, which are 8bit bitmap values of corresponding Red
, Green
and Blue
components of the color.
A
is a Alfa
coponent, the transparency value of the color. If you don't care about it, just don't show it in string output.
Upvotes: -1