转载,数度最快的图形比较 Private Declare Function CallWindowProc Lib "User32" Alias "CallWindowProcA" (lpPrevWndFunc As Any, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongFunction Hex2VBBytes(ByVal t As String) Dim i As Long, B() As Byte t = Replace(t, "\x", "") t = Replace(t, "&h", "") t = Replace(t, "0x", "") t = Replace(t, " ", "")
If Len(t) Mod 2 <> 0 Then Exit Function
ReDim B(Len(t) / 2 - 1)
For i = 0 To Len(t) / 2 - 1 B(i) = CInt("&H" & Mid(t, i * 2 + 1, 2)) Next Hex2VBBytes = B End FunctionFunction ImgCompare(SrcData As cDIB, DestData As cDIB) As Boolean Dim MapArrSrc() As Long, MapArrDest() As Long Dim i As Long, SizeImage As Long SizeImage = SrcData.mWidth * SrcData.mHeight
这样吧,临时写个函数给你,取DDB位图Long型数组,因是仅用于内存中位图的比较,所以不必管色深是多少,位图数组字节数总是4的整数倍,所以用Long型是再好不过的了。 Private 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 Private Declare Function GetCurrentObject Lib "gdi32" (ByVal hDC As Long, ByVal uObjectType As Long) As Long Private Declare Function GetObj Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As LongPublic Function GetBmpArray(Pic As Long, Optional PicType As Long) Dim i As Long Dim Bm As BITMAP, AllBytes As Long Dim Bits() As Long 'PicType指定Pic代表的含意,0时代表hDC,1时代表Bmp对象 If PicType = 0 Then i = GetCurrentObject(Pic, OBJ_BITMAP) Else i = Pic End If GetObj i, Len(Bm), Bm AllBytes = Bm.bmWidthBytes * Bm.bmHeight ReDim Bits(AllBytes \ 4 - 1) GetBitmapBits i, AllBytes, Bits(0) GetBmpArray = Bits End Function若内存位图有hdc,就直接传入,若是Picture对象,请传入Picture.Handle,并指定PicType=1,就行了。 不过若用于比较,不建议用这个函数,调用这种函数会多一次大数组的复制,耗时会增加一倍,应该将内容直接代入过程使用。
Private Declare Function CallWindowProc Lib "User32" Alias "CallWindowProcA" (lpPrevWndFunc As Any, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongFunction Hex2VBBytes(ByVal t As String)
Dim i As Long, B() As Byte
t = Replace(t, "\x", "")
t = Replace(t, "&h", "")
t = Replace(t, "0x", "")
t = Replace(t, " ", "")
If Len(t) Mod 2 <> 0 Then Exit Function
ReDim B(Len(t) / 2 - 1)
For i = 0 To Len(t) / 2 - 1
B(i) = CInt("&H" & Mid(t, i * 2 + 1, 2))
Next
Hex2VBBytes = B
End FunctionFunction ImgCompare(SrcData As cDIB, DestData As cDIB) As Boolean
Dim MapArrSrc() As Long, MapArrDest() As Long
Dim i As Long, SizeImage As Long
SizeImage = SrcData.mWidth * SrcData.mHeight
Dim CompareCode() As Byte
Dim szHexCode As String
szHexCode = "55 8B EC 8B 55 10 85 D2 76 21 8B 45 0C 8B 4D 08 56 57 8B 31 8B 38 3B F7 75 06 C7 00 00 00 00 00 83 C1 04 83 C0 04 4A 75 E9 5F 5E 5D C2 10 00"
CompareCode = Hex2VBBytes(szHexCode)
CallWindowProc CompareCode(0), SrcData.ImagePtr, DestData.ImagePtr, SizeImage, 0
ImgCompare = True
End Function
汇编里面的东西!原帖见
如何快速地判断两幅图中的不同之处?
http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=196645
说到这一点,可能很多人会觉得失望,但事实上,这种比较函数,用纯VB做可能更快。方法很简单:
用Long型数组,读出位图数据,用循环比较。这个比较过程没有任何函数调用,当你用本机码编译后,你会发现它一点也不比C慢。毕竟都是32位CPU的最佳执行代码,估计汇编后的内容都一样。而且还省去了CallWindowProc的步骤。过程调用是很耗时的,跨进程调用更是如此,我们为什么要舍近求远呢?用本机码编译,对Long循环而言,这并不是VB的弱项(各种语言都差不多),不要太相信远来的和尚会念经,而小看了VB。在我机器(CII 2.4G)上比较两个一样的1024X768X32位图,连续比较10次用时也只有40ms(因为只比较一次的用时根本计不出来)。注意:为公平起见,我计时的也只是数组循环比较部分,若算上取位图数据的时间,比较一次大约就需70ms。
有些人总是迷信API~~~
Private 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
Private Declare Function GetCurrentObject Lib "gdi32" (ByVal hDC As Long, ByVal uObjectType As Long) As Long
Private Declare Function GetObj Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As LongPublic Function GetBmpArray(Pic As Long, Optional PicType As Long)
Dim i As Long
Dim Bm As BITMAP, AllBytes As Long
Dim Bits() As Long
'PicType指定Pic代表的含意,0时代表hDC,1时代表Bmp对象
If PicType = 0 Then
i = GetCurrentObject(Pic, OBJ_BITMAP)
Else
i = Pic
End If
GetObj i, Len(Bm), Bm
AllBytes = Bm.bmWidthBytes * Bm.bmHeight
ReDim Bits(AllBytes \ 4 - 1)
GetBitmapBits i, AllBytes, Bits(0)
GetBmpArray = Bits
End Function若内存位图有hdc,就直接传入,若是Picture对象,请传入Picture.Handle,并指定PicType=1,就行了。
不过若用于比较,不建议用这个函数,调用这种函数会多一次大数组的复制,耗时会增加一倍,应该将内容直接代入过程使用。