windows mobile 开发,利用SDF实现对图像的部分像素的Lockbits!

   在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即可。

     具体过程如下:

  • 由于compact framework中不支持PixelFormat属性,因此在Lockbits时参数PixelFormat必须指定为一种,我这里是设置为常见的Format24bppRgb,即每个像素8位。
  • 使用SDF的IBitmapImage类的Lockbits函数,它可以实现对图像部分像素的锁定。
               int LockBits(
	RECT rect,     //SDF中的矩形类,与MCF不同,它的初始化参数是左上角点坐标和右下角点坐标,而不是左上角坐标和宽和高
	uint flags,    //用于指定图像被锁定的模式,只读,可写还是读写
	PixelFormat pixelFormat, //指定图像格式
	ref BitmapDataInternal lockedBitmapData   //返回被锁定的内容,它包括我们需要的scan0属性和Stride属性
         )
  • 返回锁定的内容,需要用到SDF中的BitmapDataInternal类,但是它是一个ref引用类也就是说必须在使用前赋值,参看它的构造函数得知,它需要一个BitmapData类(MCF中的)来对其初始化。
  • 使用MCF中的Bitmap的Lockbits方法对图像全部锁定,得到一个BitmapData对象,使用它来初始化SDF的BitmapDataInternal对象。
  • 接下来就可以使用IBitmapImage的Lockbits函数来锁定图像的部分像素,返回值就是引用的对象lockedBitmapData,使用它可以获得锁定内容的Scan0和Stride等属性,就可以对图像的部分像素进行下一步处理了。
  • 别忘了要释放UnlockBits(BitmapData)和UnlockBits(lockedBitmapData)

// 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 p

                for (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);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值