谢谢lyserver以及其他各位的解答,现在去研究BMP格式比较费时,时间不够了,我现在用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 GetObject 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 Long Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long Dim PicBits() As Byte Dim PicInfo As BITMAP Dim Cnt As Long Dim BytesPerLine As Long Dim xArrayx As XArrayDBPrivate Sub Command1_Click() Dim iRow As Long
如果不使用API,则set pic=loadpicture(bmpfile),然后使用point获得图片像素颜色,最后作比较。
稍复杂的办法:
创建一个内存DC,然后将该bmp选入DC,再用getpixels获得像素的颜色,最后比较。
最高效还也较复杂的办法:
重复上述步骤,但直接访问内存中的位图数据(可以使用模拟指针转换为VB的bytes数组),最后直接访问数组获得像素颜色并比较。
用:set pic=loadpicture(bmpfile),然后使用point获得图片像素颜色
这个方法非常慢,你说的另外几种方法能提供下源代码吗?
http://topic.csdn.net/t/20020409/20/634570.html
我比较忙,一般都是偷偷上一会就下了,没时间给代码。其实有了思路,实现是很容易的。
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 GetObject 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 Long
Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Dim PicBits() As Byte
Dim PicInfo As BITMAP
Dim Cnt As Long
Dim BytesPerLine As Long
Dim xArrayx As XArrayDBPrivate Sub Command1_Click()
Dim iRow As Long
GetObject Pic.Image, Len(PicInfo), PicInfo
BytesPerLine = (PicInfo.bmWidth * 3 + 3) And &HFFFFFFFC
ReDim PicBits(1 To BytesPerLine * PicInfo.bmHeight * 3) As Byte
GetBitmapBits Pic.Image, UBound(PicBits), PicBits(1)
Set xArrayx = New XArrayDB
xArrayx.Clear
xArrayx.ReDim 1, 1, 1, 3
xArrayx(1, 1) = Format(CStr(PicBits(3)), "000") & Format(CStr(PicBits(2)), ",000") & Format(CStr(PicBits(1)), ",000")
Debug.Print Format(CStr(PicBits(3)), "000") & Format(CStr(PicBits(2)), ",000") & Format(CStr(PicBits(1)), ",000")
xArrayx(1, 2) = Format(CStr(255 - PicBits(3)), "000") & Format(CStr(255 - PicBits(2)), ",000") & Format(CStr(255 - PicBits(1)), ",000")
xArrayx(1, 3) = 1
For Cnt = 5 To UBound(PicBits) Step 4
Debug.Print Format(CStr(PicBits(Cnt + 2)), "000") & Format(CStr(PicBits(Cnt + 1)), ",000") & Format(CStr(PicBits(Cnt)), ",000")
iRow = xArrayx.Find(1, 1, Format(CStr(PicBits(Cnt + 2)), "000") & Format(CStr(PicBits(Cnt + 1)), ",000") & Format(CStr(PicBits(Cnt)), ",000"))
If iRow > 0 Then
xArrayx(iRow, 3) = Val(xArrayx(iRow, 3)) + 1
Else
xArrayx.ReDim 1, xArrayx.UpperBound(1) + 1, 1, 3
xArrayx(xArrayx.UpperBound(1), 1) = Format(CStr(PicBits(Cnt + 2)), "000") & Format(CStr(PicBits(Cnt + 1)), ",000") & Format(CStr(PicBits(Cnt)), ",000")
xArrayx(xArrayx.UpperBound(1), 2) = Format(CStr(255 - PicBits(Cnt + 2)), "000") & Format(CStr(255 - PicBits(Cnt + 1)), ",000") & Format(CStr(255 - PicBits(Cnt)), ",000")
xArrayx(xArrayx.UpperBound(1), 3) = 1
End If
Next Cnt
Set tdbgDetail.Array = xArrayx
tdbgDetail.ReBind
tdbgDetail.Refresh
End Sub效率还可以,暂时满足现阶段的要求,但是我又遇到一个新问题,我在测试的时候用了几张小图
一张2×2像素的,得到的前面1/3的内容每四位记录一个点的RBG(前3位为对应颜色的G、B、R值,第4位为0,应该是分隔符),后面的2/3全部都是白色的RBG,不知道是记录什么的.。。
然后我再测试一张4×2像素的图,结果发现前面的4/9记录像素信息,后面5/9全部是黑色的RBG...
再试6×2像素,前面2/5记录像素,
再试8×2像素,前面4/9记录像素,
再试10×2像素,前面10/19记录像素
这样毫无规律可言,请问这是怎么回事阿,本人之前未接触过图片处理这块,请各位大虾指教下!先谢谢了
还有此代码的控件有PictureBox和CommandBottom各一,另外tdbgDetail是TDBGrid,大家可以屏蔽掉,不用理会
最简单的办法,创建一个内存DC和一幅32位颜色的内存位图,再把VB的图片对象使用Render方法渲染到内存DC中,这样就可以把所有图片都转换为32位的位图,然后再对内存位图进行操作,而不是对源图进行操作,结果就对了。
另外,这一类的操作,位图格式最准确,JPEG误差最大。
每个像素的位数也用 BITMAP.bmBitsPixel 判断一下,不一定都是 24 bits的。估计你计算的字节数比实际大,所以 GetBitmapBits 取得的数据只有前半段有效。
你说的颜色深度,我之前看资料的时候也看过,但是我试着用32位和24位,步长4得到的结果都一样,当时我还觉得纳闷呢?!
我现在测试用的都是24位的,用步长4读出来的RBG值都是对的阿,用步长3反而不对阿。。
究竟怎么回事阿?越弄越迷糊了,呵呵,怎么理论和我的测试效果不一样?
谢谢你的解答,测试下果然都是32bits的,和windows、photoshop说的位深度不是同一个概念?
还有BytesPerLine得到的是什么值?