【发布时间】:2012-08-26 18:30:06
【问题描述】:
正如主题所说,我有一个.bmp 图像,我需要编写一个能够获取图像任何像素颜色的代码。这是一个 1bpp(索引)图像,因此颜色将是黑色或白色。这是我目前拥有的代码:
//This method locks the bits of line of pixels
private BitmapData LockLine(Bitmap bmp, int y)
{
Rectangle lineRect = new Rectangle(0, y, bmp.Width, 1);
BitmapData line = bmp.LockBits(lineRect,
ImageLockMode.ReadWrite,
bmp.PixelFormat);
return line;
}
//This method takes the BitmapData of a line of pixels
//and returns the color of one which has the needed x coordinate
private Color GetPixelColor(BitmapData data, int x)
{
//I am not sure if this line is correct
IntPtr pPixel = data.Scan0 + x;
//The following code works for the 24bpp image:
byte[] rgbValues = new byte[3];
System.Runtime.InteropServices.Marshal.Copy(pPixel, rgbValues, 0, 3);
return Color.FromArgb(rgbValues[2], rgbValues[1], rgbValues[0]);
}
但是如何使它适用于 1bpp 图像?如果我从指针中只读取一个字节,它总是具有255 值,所以我假设我做错了什么。
请不要建议使用System.Drawing.Bitmap.GetPixel 方法,因为它工作得太慢,我希望代码尽可能快地工作。
提前致谢。
编辑: 这是可以正常工作的代码,以防万一有人需要:
private Color GetPixelColor(BitmapData data, int x)
{
int byteIndex = x / 8;
int bitIndex = x % 8;
IntPtr pFirstPixel = data.Scan0+byteIndex;
byte[] color = new byte[1];
System.Runtime.InteropServices.Marshal.Copy(pFirstPixel, color, 0, 1);
BitArray bits = new BitArray(color);
return bits.Get(bitIndex) ? Color.Black : Color.White;
}
【问题讨论】:
-
即使像素为黑色,值也是255吗?
-
当您只需要一个像素操作时,锁定位是没有意义的。您应该简单地使用 bmp 的 GetPixel 方法,而不锁定任何位或任何东西。
-
如果你真的想要多个像素,那么你应该锁定包含你想要的所有像素的整个区域,并使用 Scan0 的索引逻辑访问这些像素。
-
但是,对于单个像素获取/设置,您应该使用 GetPixel/SetPixel,因为单次使用它更快。顺便说一句,锁定 1x1 矩形可能会有问题,因此您可以尝试锁定 2x2,即使您只使用该矩形的第一个像素(如果这样做,请记住处理 bmp 的右下边缘)。
-
您的图像是每像素 1 位还是每像素 1 字节?因为你说的是24bpp,然后是1bpp,但看起来1bpp实际上意味着8bpp,或者不是?
标签: c# image image-processing monochrome