作者icools (icools)
看板C_Sharp
標題[心得] 將Bitmap 轉為Color[,] 處理在轉回分享
時間Fri Mar 14 05:54:00 2008
大家應該都知道 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