LockBits in GDI+【转】http://timothyqiu.com/archives/lockbits-in-gdiplus/
LockBits in GDI+
發布時間:March 31, 2011?分類:技術
什么東西一旦追求起效率來最終還是要歸到比較底層的操作,比如 GDI 中直接操作位圖數據就要用?GetDIBits?/?SetDIBits(或者已經廢棄的?GetBitmapBits?/?SetBitmapBits)。因為最近要處理的都是?GDI 處理不了的 PNG 格式圖片,所以還是用上了 GDI+。GDI+ 中直接操作?Bitmap?的數據就要用?LockBits?/?UnlockBits?了。
第一眼看見?Bitmap::LockBits?的聲明我就比較暈:
Status LockBits(const Rect *rect,UINT flags,PixelFormat format,BitmapData *lockedBitmapData );不過說實話,整個 GDI+ 庫的風格相對于 M$ 的其它庫來說已經是很清新脫俗了 :)
rect那么鎖定全圖進行讀操作就是:
int w = bmp->GetWidth(); int h = bmp->GetHeight(); BitmapData bmpData; bmp->LockBits(Rect(0, 0, w, h), ImageLockModeRead, PixelFormat32bppARGB, &bmpData);鎖定完圖像區域,就可以對得到的?BitmapData?進行操作了。BitmapData?包含了被鎖定區域的長、寬、格式、指針信息。取坐標 (x, y) 的像素顏色可以用:
unsigned int *pData = reinterpret_cast<unsigned int *>(bmpData.Scan0); int stride = bmpData.Stride; unsigned int color = pData[y * stride / 4 + x]; // color= 0xAARRGGBB有一個比較特別的?Stride?成員,它表示「一行」圖像對應的緩沖區所實際占用的字節數(因為位圖文件有一條變態的規則:圖片數據在存儲時每一行字節數必須是 4 的倍數,如果真實圖片數據寬度不是 4 的倍數則需要用垃圾數據補齊不足的字節數,于是就造成了?Stride?≠?Width?的現象,即所謂的字節對齊)。
對于圖片數據操作完以后要記得對鎖定區域進行解鎖:
bmp->UnlockBits(&bmpData);這樣一來就功德圓滿了。
嗯~這段筆記就是這樣,這真是有意義的一天啊~
自己提供緩沖區
咳咳~距剛剛寫這篇東西已經有大半年了,在仔細看 GDI+ 的文檔時又發現了些有用的東東。
正如你所看到的,上邊所說的「LockBits?→ 讀寫?bmpData.San0?→?UnlockBits」的三部曲其實并不與 GDI 中的?GetDIBits?/?SetDIBits?完全對應。至少后者是直接從位圖中讀取數據到我們自己提供的顏色緩沖區、直接從自己的顏色緩沖區寫到位圖中去,而前者卻需要在 Lock 后一行一行、甚至一個像素一個像素地手動交換。
好消息是?Bitmap::LockBits?的?flags?參數除了可以傳入?ImageLockModeRead?和?ImageLockModeWrite?外還可以同時或上一個?ImageLockModeUserInputBuf。這個標志位表示讓?LockBits?使用我們傳入的?BitmapData?中的緩沖區信息來進行讀寫,而不是由它來分配、我們來讀寫。
舉個栗子 :)
int w = bmp->GetWidth(); int h = bmp->GetHeight(); unsigned int *buffer = new unsigned int[w * h * 4]; // 緩沖區,以 32 位色 ARGB 模式讀取 BitmapData bmpData; bmpData.Width = w; bmpData.Height = h; bmpData.Stride = w * 4; // 緩沖區每行大小,自行分配,每行就沒有多余字節了 bmpData.Scan0 = buffer; bmpData.PixelFormat = PixelFormat32bppARGB; bmpData.Reserved = NULL; bmp->LockBits(Rect(0, 0, w, h),ImageLockModeRead | ImageLockModeUserInputBuf,PixelFormat32bppARGB,&bmpData); bmp->UnlockBits(&bmpData);轉載于:https://www.cnblogs.com/songtzu/archive/2013/01/25/2876805.html
總結
以上是生活随笔為你收集整理的LockBits in GDI+【转】http://timothyqiu.com/archives/lockbits-in-gdiplus/的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 趁热打铁-一次.Net WebServi
- 下一篇: Objective-C 学习笔记15 N