看板 C_Sharp 關於我們 聯絡資訊
大家應該都知道 GetPixel / SetPixel 的方式不適合用在大量存取 所以都會改用指標 unsafe 的方式來處理 我一開始也這樣,後來發現指標要對某個pixel的上下左右pixel 存取非常不方便(要計算) 常常不小心就會存取到不可存取記憶體區域 後來我就想說寫一個方法,一次從指標中讀出 也就是 Color[,] cr= ConverBitmap2Array(bmp) ; 如此只需要使用兩個迴圈 for(...) { for(...) { //cr[i,j].R = 230 ; cr[i,j].G =100 ; ... } } 大概就是之前 C++ 之類處理的方式 處理完後... Bitmap bmp2 = ConverArray2Bitmap(cr); 就可以取得處理過後的圖 不是什麼特殊的東西,不過我寫的時候卡在 width 和 height 迴圈位置搞錯沒發現 (記憶體會有相關) 不過終於是好了 XD 有興趣可以從我的 sky dirve下載 http://cid-c1df0d75fca0a538.skydrive.live.com/self.aspx/%e5%85%ac%e9%96%8b/Bitmap2Array.cs (cs檔不能直接用,我是直接把這兩個method 貼到文字檔上面而已 XD ,其他的類別架構自己補一下 ) 下面供參考... /// <summary> /// 將bitmap 直接轉成二維array 資料 /// </summary> /// <param name="bmpSrc"></param> /// <returns></returns> public static Color[,] ConvertBitmap2Array(Bitmap bmpSrc) { // get size int width = bmpSrc.Width; int height = bmpSrc.Height; // array data Color[,] ad = new Color[width, height]; // lockBits BitmapData dataS = bmpSrc.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); unsafe { // get remain int remain1 = dataS.Stride - dataS.Width * 3; // get ptr point byte* ptr1 = (byte*)dataS.Scan0; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { ad[j, i] = Color.FromArgb(ptr1[2], ptr1[1], ptr1[0]); ptr1 += 3; } ptr1 += remain1; } } // unLock bmpSrc.UnlockBits(dataS); return ad; } /// <summary> /// 將Array 直接轉成 Bitmap /// </summary> public static Bitmap ConvertArray2Bitmap(Color[,] ad) { // get size int width = ad.GetLength(0); int height = ad.GetLength(1); Bitmap bmpSrc = new Bitmap(width, height,PixelFormat.Format24bppRgb); // lockBits BitmapData dataS = bmpSrc.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); unsafe { // get remain int remain1 = dataS.Stride - dataS.Width * 3; // get ptr point byte* ptr1 = (byte*)dataS.Scan0; for (int i = 0; i <height ; i++) { for (int j = 0; j < width; j++) { ptr1[0] = ad[j, i].B; ptr1[1] = ad[j, i].G; ptr1[2] = ad[j, i].R; ptr1 += 3; } //cross remain mem ptr1 += remain1; } } // unLock bmpSrc.UnlockBits(dataS); return bmpSrc; -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 203.68.164.51
cczeke:非常受用 感謝 ^^ 03/14 10:57
tomex:建議操作unsafe指標時,加上fixed關鍵字比較好!! 03/14 17:21