如何快速判断两个picture是否相同?

phpro 2010-11-02 01:22:30
如果有两个picturebox,如何判断两个box中的picture是否相同?
是否可以找出两个box的picture内存段,直接进行比较?
...全文
247 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
hpygzhx520 2010-11-03
  • 打赏
  • 举报
回复
的确高人!关注一下,方便以后查找
king06 2010-11-03
  • 打赏
  • 举报
回复
收藏
贝隆 2010-11-03
  • 打赏
  • 举报
回复
呵呵,高手啊,效率的确高出很多倍,不是一个数量级的。
赵4老师 2010-11-03
  • 打赏
  • 举报
回复
将第一个图片用xor方法绘制到第二个图片上,然后检查结果不是全0(黑)就不一样

PaintPicture 方法


用以在 Form, PictureBox 或 Printer 上绘制图形文件(.bmp、.wmf、.emf、.cur、.ico或 .dib)的内容。不支持命名参数。

语法

object.PaintPicture picture, x1, y1, width1, height1, x2, y2, width2, height2, opcode


vbSrcInvert &H00660046 用 Xor 运算合并目标像素和源位图
phpro 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 chinaboyzyq 的回复:]

1、picture1.picture装入PropertyBag,然后比较字节数组。
2、图片存入磁盘,然后以二进制读入比较。
[/Quote]

这样会影响速度吗?
laviewpbt 2010-11-02
  • 打赏
  • 举报
回复


Private Type BITMAPINFOHEADER
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type

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 Const DIB_RGB_COLORS As Long = 0
Private Const OBJ_BITMAP As Long = 7
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetObjectType Lib "gdi32" (ByVal hgdiobj As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal Hdc As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal Hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal Hdc As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal Hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function CompMemory Lib "ntdll.dll" Alias "RtlCompareMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long) As Long
Private Declare Function CreateDIBSection Lib "gdi32.dll" (ByVal Hdc As Long, ByRef pBitmapInfo As Any, ByVal un As Long, ByRef Pointer As Long, ByVal Handle As Long, ByVal Dw As Long) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long



Private Function IsTheSamePicture(PicOne As StdPicture, PicTwo As StdPicture) As Boolean
Dim BmpOne As BITMAP, BmpTwo As BITMAP
Dim HandleOne As Long, HandleTwo As Long
Dim MemoryOne As Long, MemoryTwo As Long
Dim HdcOne As Long, HdcTwo As Long
Dim BmpInfo As BITMAPINFOHEADER
Dim ScreenDC As Long
Dim ByteChecked As Long
If GetObjectType(PicOne.Handle) <> OBJ_BITMAP Or GetObjectType(PicTwo.Handle) <> OBJ_BITMAP Then
IsTheSamePicture = False
Else
GetObject PicOne.Handle, Len(BmpOne), BmpOne
GetObject PicTwo.Handle, Len(BmpTwo), BmpTwo
If BmpOne.bmWidth <> BmpTwo.bmWidth Or BmpOne.bmHeight <> BmpTwo.bmHeight Or BmpOne.bmBitsPixel <> BmpTwo.bmBitsPixel Then
IsTheSamePicture = False
ElseIf BmpOne.bmBits <> 0 And BmpTwo.bmBits <> 0 Then
ByteChecked = CompMemory(ByVal BmpOne.bmBits, ByVal BmpTwo.bmBits, BmpOne.bmWidthBytes * BmpOne.bmHeight)
IsTheSamePicture = CBool(ByteChecked = BmpOne.bmWidthBytes * BmpOne.bmHeight)
Else
If BmpOne.bmBits <> 0 Then
MemoryOne = BmpOne.bmBits
Else

ScreenDC = GetDC(0)
HdcOne = CreateCompatibleDC(ScreenDC)
With BmpInfo
.biSize = 40
.biBitCount = 24
.biHeight = BmpOne.bmHeight
.biWidth = BmpOne.bmWidth
.biPlanes = 1
.biSizeImage = ((BmpOne.bmWidth * 3 + 3) And &HFFFFFFFC) * BmpOne.bmHeight
End With
HandleOne = CreateDIBSection(HdcOne, BmpInfo, DIB_RGB_COLORS, MemoryOne, 0, 0)
SelectObject HdcOne, HandleOne
PicOne.Render HdcOne + 0&, 0&, 0&, BmpOne.bmWidth + 0&, BmpOne.bmHeight + 0&, 0, PicOne.Height, PicOne.Width, -PicOne.Height, ByVal 0
ReleaseDC 0, ScreenDC
End If
If BmpTwo.bmBits <> 0 Then
MemoryTwo = BmpTwo.bmBits
Else
ScreenDC = GetDC(0)
HdcTwo = CreateCompatibleDC(ScreenDC)
With BmpInfo
.biSize = 40
.biBitCount = 24
.biHeight = BmpTwo.bmHeight
.biWidth = BmpTwo.bmWidth
.biPlanes = 1
.biSizeImage = ((BmpTwo.bmWidth * 3 + 3) And &HFFFFFFFC) * BmpTwo.bmHeight
End With
HandleTwo = CreateDIBSection(HdcTwo, BmpInfo, DIB_RGB_COLORS, MemoryTwo, 0, 0)
SelectObject HdcTwo, HandleTwo
PicTwo.Render HdcTwo + 0&, 0&, 0&, BmpTwo.bmWidth + 0&, BmpTwo.bmHeight + 0&, 0, PicTwo.Height, PicTwo.Width, -PicTwo.Height, ByVal 0 '类似于BMP的逆序存储,所以用-StdPic.Height
ReleaseDC 0, ScreenDC
End If
ByteChecked = CompMemory(ByVal MemoryOne, ByVal MemoryTwo, BmpInfo.biSizeImage)
IsTheSamePicture = CBool(ByteChecked = BmpInfo.biSizeImage)
If HdcOne <> 0 Then DeleteDC HdcOne
If HdcTwo <> 0 Then DeleteDC HdcTwo
If HandleOne <> 0 Then DeleteObject HandleOne
If HandleTwo <> 0 Then DeleteObject HandleTwo
End If
End If
End Function


chinaboyzyq 2010-11-02
  • 打赏
  • 举报
回复
1、picture1.picture装入PropertyBag,然后比较字节数组。
2、图片存入磁盘,然后以二进制读入比较。
soarsoar77 2010-11-02
  • 打赏
  • 举报
回复
最后的办法不错,如果只要得到结果是否相同的话,非常好
如果要指出是哪些地方不相同,估计还是逐点比较来的方便
dingyanwei 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 veron_04 的回复:]
引用 15 楼 dingyanwei 的回复:
我看最简单的办法就是将picturebox中的图像存为文件后判断hash值

怎么hash?
[/Quote]

md5或crc校验
贝隆 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 dingyanwei 的回复:]
我看最简单的办法就是将picturebox中的图像存为文件后判断hash值
[/Quote]
怎么hash?
dingyanwei 2010-11-02
  • 打赏
  • 举报
回复
我看最简单的办法就是将picturebox中的图像存为文件后判断hash值
evergod82 2010-11-02
  • 打赏
  • 举报
回复
方法还不少呢!
PctGL 2010-11-02
  • 打赏
  • 举报
回复
给 picturebox 做截图, 取位图数据
然后循环直接比较位图的像素值,非常快
贝隆 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 kill2010 的回复:]
我觉得的先排除不一样的情况,比如:
判断文件容量大小,高度、宽度,有不一致的情况立即判定不一样
这样速度就高些


引用 10 楼 veron_04 的回复:
VB code

Option Explicit
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByV……
[/Quote]
对的,这样最好
Kill2010 2010-11-02
  • 打赏
  • 举报
回复
我觉得的先排除不一样的情况,比如:
判断文件容量大小,高度、宽度,有不一致的情况立即判定不一样
这样速度就高些

[Quote=引用 10 楼 veron_04 的回复:]
VB code

Option Explicit
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function MessageBox Lib "user32" Alias "Message……
[/Quote]
贝隆 2010-11-02
  • 打赏
  • 举报
回复

Option Explicit
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub Command1_Click()
Dim lngW As Long
Dim lngH As Long
Dim lngP As Long
Dim lngT As Long
Dim lngD As Long
Dim lngColor(0 To 1) As Long
On Error GoTo errSub
lngW = picP(0).ScaleWidth
lngH = picP(0).ScaleHeight
lngD = GetTickCount
For lngP = 0 To lngW
For lngT = 0 To lngH
lngColor(0) = GetPixel(picP(0).hdc, lngP, lngT)
lngColor(1) = GetPixel(picP(1).hdc, lngP, lngT)
If lngColor(0) <> lngColor(1) Then
MessageBox hwnd, "图片不一样!比较用时:" & GetTickCount - lngD & "ms", "系统提示", vbOKOnly + vbExclamation

Exit Sub
End If
Next lngT
Next lngP
MessageBox hwnd, "图片一致!比较用时:" & GetTickCount - lngD & "ms", "系统提示", vbOKOnly + vbExclamation
Exit Sub
errSub:
End Sub

Private Sub Form_Load()
Dim lngP As Long
On Error GoTo errSub
picP(0).ScaleMode = 3
picP(1).ScaleMode = 3
picP(0).Picture = LoadPicture("E:\文档资料\图片资料\G.Batistuta\1.bmp")
picP(1).Picture = LoadPicture("E:\文档资料\图片资料\G.Batistuta\1.bmp")
Exit Sub
errSub:
End Sub

phpro 2010-11-02
  • 打赏
  • 举报
回复
用GetPixel逐点比较会不会很慢
dbcontrols 2010-11-02
  • 打赏
  • 举报
回复
这样啊,那还是请laviewpbt给个好的答案好了

[Quote=引用 7 楼 veron_04 的回复:]
引用 5 楼 laviewpbt 的回复:
请问 楼上GetPixel 创意何在?

呵呵!我的第一反应就是把图片二值化,他的这个方法我没有想到,对我来说就是有创意 :),速度虽然慢,但简单易行,也不是不可行的。
[/Quote]
贝隆 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 laviewpbt 的回复:]
请问 楼上GetPixel 创意何在?
[/Quote]
呵呵!我的第一反应就是把图片二值化,他的这个方法我没有想到,对我来说就是有创意 :),速度虽然慢,但简单易行,也不是不可行的。
dbcontrols 2010-11-02
  • 打赏
  • 举报
回复
我也纳闷,这种方法是很笨的,速度也慢。

[Quote=引用 5 楼 laviewpbt 的回复:]
请问 楼上GetPixel 创意何在?
[/Quote]
加载更多回复(3)

809

社区成员

发帖
与我相关
我的任务
社区描述
VB 多媒体
社区管理员
  • 多媒体
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧