(vb)利用GetBitmapBits,SetBitmapBits加速影像處理 (轉)

gugu99發表於2007-08-15
(vb)利用GetBitmapBits,SetBitmapBits加速影像處理 (轉)[@more@]

(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,目標點陣圖的控制程式碼

其中用到的Get,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, tmpInfo 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,sp3),處理一副600*800的圖片,
在中執行約0.8秒,
編譯成exe,編譯選項是"Optimize for Fast Code".執行,<0.4秒

有興趣的可以試試用SetPixelV,GetPixel做上面的事情,肯定會慢許多
SetPixelV,GetPixel對應的vb的方法是pset,point,這個就沒必要試了,這個慢得更厲害

  lingll
  -7-5


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-958606/,如需轉載,請註明出處,否則將追究法律責任。

相關文章