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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章