How to
Compare
Two
Bitmaps
for
Equality
The
first
thing to
do is
compare
the
HBITMAP
handles
themselves.
If they
are the
same
handle,
then the
two
bitmaps
are
obviously
equal.
If one
of the
handles
is
NULL
,
then
they are
obviously
not
equal.
If the
HBITMAP
handles
are
different
and not
NULL
,
then use
GetDIBits
to fill
two
BITMAPINFO
structures
-- one
for each
bitmap
-- and
compare
the
BITMAPINFOHEADER
s.
If the
BITMAPINFOHEADER
s
contain
different
data,
then the
bitmaps
are
different.
If they
contain
the same
data,
then the
next
step is
to
compare
the
actual
bitmap
data
bits.
The Code
Collapse
|
Copy
Code
bool CompareBitmaps(HBITMAP HBitmapLeft, HBITMAP HBitmapRight)
{
if (HBitmapLeft == HBitmapRight)
{
return true;
}
if (NULL == HBitmapLeft || NULL == HBitmapRight)
{
return false;
}
bool bSame = false;
HDC hdc = GetDC(NULL);
BITMAPINFO BitmapInfoLeft = {0};
BITMAPINFO BitmapInfoRight = {0};
BitmapInfoLeft.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BitmapInfoRight.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
if (0 != GetDIBits(hdc, HBitmapLeft, 0, 0, NULL, &BitmapInfoLeft, DIB_RGB_COLORS) &&
0 != GetDIBits(hdc, HBitmapRight, 0, 0, NULL, &BitmapInfoRight, DIB_RGB_COLORS))
{
if (0 == memcmp(&BitmapInfoLeft.bmiHeader, &BitmapInfoRight.bmiHeader,
sizeof(BITMAPINFOHEADER)))
{
BYTE *pLeftBits = new BYTE<BitmapInfoLeft.bmiHeader.biSizeImage>;
BYTE *pRightBits = new BYTE<BitmapInfoRight.bmiHeader.biSizeImage>;
BYTE *pByteLeft = NULL;
BYTE *pByteRight = NULL;
PBITMAPINFO pBitmapInfoLeft = &BitmapInfoLeft;
PBITMAPINFO pBitmapInfoRight = &BitmapInfoRight;
int AdditionalMemory = 0;
switch (BitmapInfoLeft.bmiHeader.biBitCount)
{
case 1:
AdditionalMemory = 1 * sizeof(RGBQUAD);
break;
case 4:
AdditionalMemory = 15 * sizeof(RGBQUAD);
break;
case 8:
AdditionalMemory = 255 * sizeof(RGBQUAD);
break;
case 16:
case 32:
AdditionalMemory = 2 * sizeof(RGBQUAD);
}
if (AdditionalMemory)
{
pByteLeft = new BYTE[sizeof(BITMAPINFO) + AdditionalMemory];
if (pByteLeft)
{
memset(pByteLeft, 0, sizeof(BITMAPINFO) + AdditionalMemory);
memcpy(pByteLeft, pBitmapInfoLeft, sizeof(BITMAPINFO));
pBitmapInfoLeft = (PBITMAPINFO)pByteLeft;
}
pByteRight = new BYTE[sizeof(BITMAPINFO) + AdditionalMemory];
if (pByteRight)
{
memset(pByteRight, 0, sizeof(BITMAPINFO) + AdditionalMemory);
memcpy(pByteRight, pBitmapInfoRight, sizeof(BITMAPINFO));
pBitmapInfoRight = (PBITMAPINFO)pByteRight;
}
}
if (pLeftBits && pRightBits && pBitmapInfoLeft && pBitmapInfoRight)
{
memset(pLeftBits, 0, BitmapInfoLeft.bmiHeader.biSizeImage);
memset(pRightBits, 0, BitmapInfoRight.bmiHeader.biSizeImage);
if (0 != GetDIBits(hdc, HBitmapLeft, 0,
pBitmapInfoLeft->bmiHeader.biHeight, pLeftBits, pBitmapInfoLeft,
DIB_RGB_COLORS) && 0 != GetDIBits(hdc, HBitmapRight, 0,
pBitmapInfoRight->bmiHeader.biHeight, pRightBits, pBitmapInfoRight,
DIB_RGB_COLORS))
{
bSame = 0 == memcmp(pLeftBits, pRightBits,
pBitmapInfoLeft->bmiHeader.biSizeImage);
}
}
delete[] pLeftBits;
delete[] pRightBits;
delete[] pByteLeft;
delete[] pByteRight;
}
}
ReleaseDC(NULL, hdc);
return bSame;
}