GDIVisual Studio .NET 2002Visual C++ 7.1Visual C++ 8.0Visual Studio 6Visual C++ 7.0Visual Studio .NET 2003Visual Studio 2005Windows 2000Visual C++ 6.0Windows XPMFC中级开发Visual StudioWindowsC++
比较两个位图的相等性
代码片段,
引言
这里介绍了一种简单的方法来比较两个 HBITMAP
句柄,以查看它们是否包含相同的位图。 代码本身没有什么特别之处,所以我将直接将其包含在文章正文中。 不需要单独的下载或演示应用程序。
如何比较两个位图是否相等
首先要做的是比较 HBITMAP
句柄本身。 如果它们是相同的句柄,那么这两个位图显然相等。 如果其中一个句柄为 NULL
,那么它们显然不相等。 如果 HBITMAP
句柄不同且不为 NULL
,则使用 GetDIBits
填充两个 BITMAPINFO
结构体——每个位图一个——并比较 BITMAPINFOHEADER
。 如果 BITMAPINFOHEADER
包含不同的数据,则位图不同。 如果它们包含相同的数据,那么下一步是比较实际的位图数据位。
代码
/////////////////////////////////////////////////////////////////////////////
//
// CompareBitmaps
// Compares two HBITMAPs to see if they contain the same image
//
// Parameters :
// HBitmapLeft [in] : The HBITMAP handles that are to be compared
// HBitmapRight [in] :
//
// Returns :
// true if the bitmaps are the same
// false if they are different
//
/////////////////////////////////////////////////////////////////////////////
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))
{
// Compare the BITMAPINFOHEADERs of the two bitmaps
if (0 == memcmp(&BitmapInfoLeft.bmiHeader, &BitmapInfoRight.bmiHeader,
sizeof(BITMAPINFOHEADER)))
{
// The BITMAPINFOHEADERs are the same so now compare the actual bitmap bits
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;
// calculate the size in BYTEs of the additional
// memory needed for the bmiColor table
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)
{
// we have to allocate room for the bmiColor table that will be
// attached to our BITMAPINFO variables
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)
{
// zero out the bitmap bit buffers
memset(pLeftBits, 0, BitmapInfoLeft.bmiHeader.biSizeImage);
memset(pRightBits, 0, BitmapInfoRight.bmiHeader.biSizeImage);
// fill the bit buffers with the actual bitmap bits
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))
{
// compare the actual bitmap bits of the two bitmaps
bSame = 0 == memcmp(pLeftBits, pRightBits,
pBitmapInfoLeft->bmiHeader.biSizeImage);
}
}
// clean up
delete[] pLeftBits;
delete[] pRightBits;
delete[] pByteLeft;
delete[] pByteRight;
}
}
ReleaseDC(NULL, hdc);
return bSame;
}
历史
- 2006年12月19日 -- 发布原始版本
- 2008年3月12日 -- 编辑文章并移动到 Code Project 主文章库