Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Comparing Bitmaps

0 views
Skip to first unread message

Dave Oakes

unread,
Oct 14, 2001, 1:30:20 PM10/14/01
to
Hi

Is there any way to see if two bitmaps (in picture boxes) are
identical without checking each pixel.

Thanks In Advance.

Harvey Triana

unread,
Oct 14, 2001, 7:54:57 AM10/14/01
to
Dave~
Open the two Pictures from files using binary access, read String variables in
blobs (say 1024 bytes), and compare this variables. Loop until EOF.
________________________________
Harvey Triana... han...@latino.net.co
Microsoft Developer MVP- Visual Basic
www.eidos.es/VeXPERT

"Dave Oakes" <djo_SPAM__...@dial.ipex.com> escribió en el mensaje
news:3bcacb68...@news.dial.pipex.com...

Dave Oakes

unread,
Oct 14, 2001, 9:53:37 PM10/14/01
to
On Sun, 14 Oct 2001 06:54:57 -0500, "Harvey Triana"
<_han...@latino.net.co> wrote:

>Dave~
>Open the two Pictures from files using binary access, read String variables in
>blobs (say 1024 bytes), and compare this variables. Loop until EOF.

Thanks, but the pictures are not directly read from files so to do
this would presumably require creating temp files for each picture.
Also although the pictures are small (16x16x16bit) there could be upto
200 of them so making temp files for each would take far too long.
Is there someway of perhaps copying the contents of a picture box into
to a string or byte array?

Thanks for your reply

Best Regards.
Dave.

Larry Serflaten

unread,
Oct 14, 2001, 10:45:40 PM10/14/01
to

"Dave Oakes" <djo_SPAM__...@dial.ipex.com> wrote

> >Dave~
> >Open the two Pictures from files using binary access, read String variables in
> >blobs (say 1024 bytes), and compare this variables. Loop until EOF.
>
> Thanks, but the pictures are not directly read from files so to do
> this would presumably require creating temp files for each picture.
> Also although the pictures are small (16x16x16bit) there could be upto
> 200 of them so making temp files for each would take far too long.
> Is there someway of perhaps copying the contents of a picture box into
> to a string or byte array?

I know I've seen a method to get at the DIB bits, but that was years ago,
now. What I would suggest for the larger pictures, might also work in
your case as well.

If you use BitBlt to Xor two pictures together, all pixels will be 0 (black)
that are identical, or the difference value if they are different. Once you
do that you can tell (visually) if they are close to identical by the amount
of black, identical pictures would be entirely black.

Once you have that (temporary) difference image, you could effectively
find if any pixel is different by folding the image onto itself until it is
small enough to check using GetPixel (Approx 8 X 8 or less). By
folding, I mean to copy (using BitBlt for example) the top half of the
picture, to the bottom half using an OR type operation, then toss
out the top half, and continue folding the bottom. Because you use
a logical OR in the copy process, any differences from the top half,
will be added to the bottom. You can then forget about checking the
top half, and continue working with only the bottom half. (Or vise
versa, copy bottom to the top, if that is conceptually easier to follow)

You might fold it once vertically, then once horizontally, then vertically,
and again horizontally, until you get to a more managble 8 X 8 size, or
in your case you might want to go to 2 X 2. At 2 X 2 you only
have to check 4 pixels to tell if there is 'any' difference in the two images.
(If there are any odd sizes, the source you are copying, has to be smaller
than the destination you are copying to, to capture all pixels)

As you can see, this folding will reduce the larger images rather quickly.
It may not be exceptionally fast, if you have to compare 200 images,
but it may give you respectable results compared to other VB methods.

Have fun!
LFS

Howard Henry Schlunder

unread,
Oct 15, 2001, 12:58:45 AM10/15/01
to
To ask if two bitmaps are the same without checking each pixel is akin to asking if two letters are the same without actually reading them. Although varying methods may have varying performace characteristics, ultimately, every pixel's bits will need to be compared. Anyway, I'd suggest using the GetBitmapBits API function:

Option Explicit
Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long

Private Sub Command1_Click()
Debug.Print ComparePictures(Picture1, Picture2)
End Sub

Private Function ComparePictures(ByRef Picture1 As PictureBox, ByRef Picture2 As PictureBox) As Boolean
Dim i As Long
Dim BMPBits1() As Byte, BuffSize1 As Long
Dim BMPBits2() As Byte, BuffSize2 As Long
BuffSize1 = CLng(Picture1.ScaleX(Picture1.Image.Width, vbHimetric, vbPixels) * Picture1.ScaleY(Picture1.Image.Height, vbHimetric, vbPixels))
BuffSize2 = CLng(Picture2.ScaleX(Picture2.Image.Width, vbHimetric, vbPixels) * Picture2.ScaleY(Picture2.Image.Height, vbHimetric, vbPixels))
If BuffSize1 <> BuffSize2 Then Exit Function 'Pictures aren't even the same size
ReDim BMPBits1(0 To BuffSize1 - 1)
ReDim BMPBits2(0 To BuffSize2 - 1)
If GetBitmapBits(Picture1.Image.Handle, BuffSize1, BMPBits1(0)) Then
If GetBitmapBits(Picture2.Image.Handle, BuffSize2, BMPBits2(0)) Then
For i = 0 To BuffSize1 - 1
If Not BMPBits1(i) = BMPBits2(i) Then Exit Function
Next i
ComparePictures = True
End If
End If
End Function

Howard Henry Schlunder

"Dave Oakes" <djo_SPAM__...@dial.ipex.com> wrote in message news:3bcacb68...@news.dial.pipex.com...

Dave Oakes

unread,
Oct 15, 2001, 1:24:53 PM10/15/01
to

Hi

Funnily enough that is exactly what I am alreadty doing, more or less,
ORing the 2 images and then quartering it to leave a 8x8 image and
then looking at each pixel until I find a non-black one. I had hoped
there was a simpler and quicker way to do it

Many thanks for the suggestion
Dave.

Dave Oakes

unread,
Oct 15, 2001, 1:29:48 PM10/15/01
to

Hi

Splendid, I think the solution will probably be a hybrid of Larrys
solution and yours, OR the two pictures together then use
GetBitmapBits to read the resulting image into a byte array then just
loop through looking for non zero array elements.

Many thanks
Dave.

Larry Serflaten

unread,
Oct 15, 2001, 3:28:38 PM10/15/01
to

"Dave Oakes" <djo_SPAM__...@dial.ipex.com> wrote


> Splendid, I think the solution will probably be a hybrid of Larrys
> solution and yours, OR the two pictures together then use
> GetBitmapBits to read the resulting image into a byte array then just
> loop through looking for non zero array elements.

Are you not going to have to XOR them together?

For any one pixel:

vbYellow OR vbYellow = VbYellow
vbYellow XOR vbYellow = vbBlack (0)

Perhaps a typo?

LFS


Dave Oakes

unread,
Oct 15, 2001, 4:38:12 PM10/15/01
to

Hi

Yup a typo, I've done some testing and found that XORing to a 8 x 8
image then using GetDIBits rather than GetBitmapBits (apparently
obsolete in win32) to copy to a byte array then as above seems to be
the fastest solution. XORing any further gives no significant speed
increase.

Best Regards
Dave.

0 new messages