在windows mobile开发中,遇到一个问题,在.net compact framework框架下的Lockbits函数不能对图像的部分像素进行锁定,由于程序中必须用到该操作,因此试图看能否解决这个问题,最后找到的解决方案就是借助smart device framework类库,只需要寥寥几行代码就可以实现这个功能,不错,很好很强大。
之前已经介绍过了smart device framework的安装,如果要使用它,只需要在项目中添加引用--》将需要的SDF的dll文件添加进来,同时在程序中开始部分添加对命名空间的引用,我这里只用了OpenNETCF.dll和OpenNETCF.Drawing.dll两个文件,因此只需要添加using OpenNETCF.Drawing和Using OpenNETCF.Drawing.Imaging、using OpenNETCF即可。
具体过程如下:
int LockBits( RECT rect, //SDF中的矩形类,与MCF不同,它的初始化参数是左上角点坐标和右下角点坐标,而不是左上角坐标和宽和高 uint flags, //用于指定图像被锁定的模式,只读,可写还是读写 PixelFormat pixelFormat, //指定图像格式 ref BitmapDataInternal lockedBitmapData //返回被锁定的内容,它包括我们需要的scan0属性和Stride属性 )
// convert the pixel format of the bitmap to something that we can handle
PixelFormat pf = CheckSupportedPixelFormat(PixelFormat.Format24bppRgb);IBitmapImage iBitmap;
BitmapDataInternal bmData;int xMax, yMax;
//----------------------------------------------
Rectangle fullImageSize = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData netBmData = bmp.LockBits(fullImageSize, System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);bmData = new BitmapDataInternal(netBmData);
ImagingFactory imgfactory = new ImagingFactory();imgfactory.CreateBitmapFromBuffer(ref bmData, out iBitmap);
RECT HorizeImageSize = new RECT(start, 0, end, bmp.Height);
RECT VerticalImageSize = new RECT(0, start, bmp.Width, end);if (direction == ScanDirection.Horizontal)
{
//NCF下Lockbits不支持部分锁定
//bmData = bmp.LockBits(new Rectangle(start, 0, end - start, bmp.Height), ImageLockMode.ReadOnly, pf);//第一步:将NCF标准bitmap类转换为NCF下的IBitmapImage类
iBitmap.LockBits(HorizeImageSize, (uint)System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb, ref bmData);
xMax = bmData.Height;
yMax = end - start;
}
else
{//bmData = bmp.LockBits(new Rectangle(0, start, bmp.Width, end - start), ImageLockMode.ReadOnly, pf);
iBitmap.LockBits(VerticalImageSize, (uint)System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb, ref bmData);
xMax = bmp.Width;
yMax = bmData.Height;
}// Create the return value
byte[] histResult = new byte[xMax + 2]; // add 2 to simulate light-colored background pixels at sart and end of scanline
ushort[] vertSum = new ushort[xMax];unsafe
{
byte* p = (byte*)(void*)bmData.Scan0;
int stride = bmData.Stride; // stride is offset between horizontal lines in pfor (int y = 0; y < yMax; ++y)
{
// Add up all the pixel values vertically
for (int x = 0; x < xMax; ++x)
{
if (direction == ScanDirection.Horizontal)
vertSum[x] += getpixelbrightness(p, pf, stride, y, x);
else
vertSum[x] += getpixelbrightness(p, pf, stride, x, y);
}
}
}bmp.UnlockBits(netBmData);
iBitmap.UnlockBits(ref bmData);