(vb)利用GetBitmapBits,SetBitmapBits加速影像處理
(不知道前面有沒有人寫過這個,這裡主要是最近寫程式的一些心得,希望對大家有用.久未寫東西,會有一堆的毛病,將就著吧.)
最近發現了兩個好東東,SetBitmapBits,GetBitmapBits,能極大的提高某些影像處理的速度.
引用別人的話
"SetBitmapBits:
vb聲明: Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
作用: "將來自緩衝區的二進位位複製到一幅位元影像"
參數: hBitmap Long,位元影像的控制代碼
dwCount Long,欲複製的位元組數量
lpBits Any,指向一個緩衝區的指標。這個緩衝區包含了為位元影像正確格式化的位元影像位
GetBitmapBits:
vb聲明: Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
作用: "將來自位元影像的二進位位複製到一個緩衝區"
參數: hBitmap Long,位元影像的控制代碼
dwCount Long,欲複製的位元組數。如設為零,表示取得位元影像中的位元組數
lpBits Any,指向容納位元影像位的一個緩衝區的指標。注意事先將緩衝區至少初始化成dwCount個位元組 "
舉一個例子,將圖片旋轉90度,下面是我寫的順時針旋轉90度的函數.
假設靶心圖表像的寬等於源圖的長,靶心圖表像的長等於源圖的寬,兩圖顏色值佔用的位元相等.
參數: hSrcBmp,源圖位元影像的控制代碼,vb中對應的是Picture.Handle
hDestBmp,目標位元影像的控制代碼
其中用到的GetObject,CopyMemory函數與BITMAP類型,聲明如下
Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)
Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
'順時針旋轉90度的函數:
Public Function TurnBmp(hSrcBmp As Long, hDestBmp As Long) As Boolean
Dim X As Long, Y As Long
Dim BytesPixel As Long
Dim tSBmpInfo As BITMAP, tDBmpInfo As BITMAP
Dim sBits() As Byte, dBits() As Byte
'獲得位元影像資訊
Call GetObject(hSrcBmp, Len(tSBmpInfo), tSBmpInfo)
Call GetObject(hDestBmp, Len(tDBmpInfo), tDBmpInfo)
'申請空間
ReDim sBits(1 To tSBmpInfo.bmWidthBytes, 1 To tSBmpInfo.bmHeight)
ReDim dBits(1 To tDBmpInfo.bmWidthBytes, 1 To tDBmpInfo.bmHeight)
'獲得源圖與靶心圖表二進位位
Call GetBitmapBits(hSrcBmp, tSBmpInfo.bmWidthBytes * tSBmpInfo.bmHeight, sBits(1, 1))
Call GetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, dBits(1, 1))
'計算顏色值佔用多少位元組
BytesPixel = tSBmpInfo.bmBitsPixel / 8
'旋轉
For Y = 1 To tSBmpInfo.bmHeight
For X = 1 To tSBmpInfo.bmWidth
Call CopyMemory(dBits((tSBmpInfo.bmHeight - Y) * BytesPixel + 1, X), sBits((X - 1) * BytesPixel + 1, Y), BytesPixel)
Next X
Next Y
'將旋轉的結果複製到目標位元影像
Call SetBitmapBits(hDestBmp, tDBmpInfo.bmWidthBytes * tDBmpInfo.bmHeight, dBits(1, 1))
End Function
'調用,一定要用image屬性,不然會有問題
Call TurnBmp(Picture1.Image.handle, Picture2.Image.handle)
在我的機上(獨龍600,win2ksp3),處理一副600*800的圖片,
在ide中運行約0.8秒,
編譯成exe,編譯選項是"Optimize for Fast Code".運行,<0.4秒
有興趣的可以試試用SetPixelV,GetPixel做上面的事情,肯定會慢許多
SetPixelV,GetPixel對應的vb的方法是pset,point,這個就沒必要試了,這個慢得更厲害
lingll
2003-7-5