返回首页

简介
这里介绍的是一个简单的方法来比较两个HBITMAP句柄,看看他们是否包含相同的位图。代码本身是没有任何幻想,所以我只是将它包括在文章中的文字。没有单独下载或演示应用程序是必要的。如何比较平等的两个位图
要做的第一件事是比较HBITMAP处理自己。如果它们是相同的处理,然后两个位图,显然是平等的。如果其中一个手柄是NULL,那么他们显然不等于。如果HBITMAP处理是不同的,不为NULL,然后使用GetDIBits,以填补两个BITMAPINFO结构 - 每个位图 - 比较BITMAPINFOHEADERs。如果BITMAPINFOHEADERs包含不同的数据,然后位图是不同的。如果它们包含相同的数据,那么下一步是比较实际的位图数据位。"守则"

/////////////////////////////////////////////////////////////////////////////

//

//  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日 - 原始版本发布12年3月,2008年 - 编辑和移动的代码项目主要文章基地

回答

评论会员:亚历山大Shilonosov 时间:2011/12/07
谢谢你的代码。
在我的项目中,我需要比较的截图,并允许为他们轻微的变化(假设我从一个窗口截图定期)。

所以代码返回True - 只有图像是相同的,或者有一点点的变化,它在(1K块不到3%是不同的。)

下面是代码:

INT Different_blocks = 0;
/ / 1K块扫描,并找出有多少块是不同的。(我= 0; ILT; = pBitmapInfoLeft - GT; bmiHeader.biSizeImage / 1000; I)
{
(memcmp(pLeftBits我* 1000,pRightBits我* 1000,1000))
Different_blocks;

}

bSame = TRUE; / /设置允许的限制 - 从总块数的3.3%
。allowed_limit =(pBitmapInfoLeft - GT; bmiHeader.biSizeImage / 10000)/ 3;
(Different_blocks GT; allowed_limit)
bSame = FALSE;
-
亚历山大Shilonosov
评论会员:Mikke8 时间:2011/12/07
?在移植到C的人已经
我需要的C。

编辑:
已经做了=)
这里是代码

int CompareBitmaps(HBITMAP HBitmapLeft, HBITMAP HBitmapRight)

{

    if (HBitmapLeft == HBitmapRight)

    {

        return 1;

    }

 

    if (NULL == HBitmapLeft || NULL == HBitmapRight)

    {

        return 0;

    }

 

    int bSame = 0;

    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 = (BYTE *) malloc(sizeof(BYTE) * BitmapInfoLeft.bmiHeader.biSizeImage);

            BYTE *pRightBits = (BYTE *) malloc(sizeof(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 = (BYTE*) malloc(sizeof(BYTE) * (sizeof(BITMAPINFO) + AdditionalMemory));

                if (pByteLeft)

                {

                    memset(pByteLeft, 0, sizeof(BITMAPINFO) + AdditionalMemory);

                    memcpy(pByteLeft, pBitmapInfoLeft, sizeof(BITMAPINFO));

                    pBitmapInfoLeft = (PBITMAPINFO)pByteLeft;

                }

 

                pByteRight = (BYTE *) malloc(sizeof(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



                    FILE *f1 = fopen("C:\\Coding\\Log1.txt", "w");

                    FILE *f2 = fopen("C:\\Coding\\Log2.txt", "w");

                    fprintf(f1, "%s", (CHAR *) pLeftBits);

                    fprintf(f2, "%s", (CHAR *) pRightBits);

                    fflush(f1);

                    fflush(f2);

                    fclose(f1);

                    fclose(f2);

                    bSame = 0 == memcmp(pLeftBits, pRightBits, 

                        pBitmapInfoLeft->bmiHeader.biSizeImage);

                }

            }

 

            // clean up



            free(pLeftBits);

            free(pRightBits);

            free(pByteLeft);

            free(pByteRight);

        }

    }

 

    ReleaseDC(NULL, hdc);

 

    return bSame;

}


修改日(星期四),1月28日,2010下午08:07
评论会员:会员1372339 时间:2011/12/07
{S0}您好,

我做了一个包含此功能的DLL,当我调用它来比较两个hbitmaps - 崩溃的:
memset的(pLeftBits BitmapInfoLeft.bmiHeader.biSizeImage,0);
(出位图缓冲区零)

最高审计机关 - "访问冲突的地址XY写"。当我评论这两个memsets - 它不会崩溃,但它返回false,当我把它传递了两个相同的图像 - 一个屏幕后的另一个领域的两个bitblts ... ...
问题出在哪里。你可以只使用后的memset

BYTE * pLeftBits =新的字节;

不分配的内存pLeftBits?


Hrvoje
评论会员:PJArends 时间:2011/12/07
CodeProject上莫名其妙地弄乱了这篇文章的源代码。如果此页面上的"查看源",你会​​看到正确的代码。我会得到一个编辑器来修复它。但在平均时间,你可以改变的两行:
BYTE *pLeftBits = new BYTE[BitmapInfoLeft.bmiHeader.biSizeImage];

BYTE *pRightBits = new BYTE[BitmapInfoRight.bmiHeader.biSizeImage];
。我希望这会有所帮助。
  ;
评论会员:ceejeeb 时间:2011/12/07
这是一个伟大的文章,但你知不知道我怎么能扩展到第三位图是黑色和白色,并在所有白色像素,代表了两个位图的区别?
评论会员:PJArends 时间:2011/12/07
一个简单的方法是创建一个所需大小的单色位图,并做一个对前两个位图简单的GetPixel和一个新的SetPixel
for (int w = 0; w < width; ++w)

{

   for (int h = 0; h < height; ++h)

   {

      if (GetPixel(DC1, w, h) != GetPixel(DC2, w, h))

         SetPixel(DCNew, w, h, RGB(255, 255, 255));

      else

         SetPixel(DCNew, w, h, RGB(0, 0, 0));

   }

}


你可能是正确
我可能是疯了
- 比利乔 -

在你的谎言好,用它
电源
评论会员:!ceejeeb 时间:2011/12/07
您好,{ BR}
表示感谢,我看您去,但IM不熟悉这个话题,你能解释一下你将如何创建一个单色位图,你将如何得到位图的高度和宽度。感谢。
评论会员:PJArends 时间:2011/12/07
位图的宽度和高度都在上面的代码中引用的BITMAPINFOHEADER。也可以通过调用GetObject()获得,您填写的HBITMAP对象从一个BITMAP结构

使用CreateBitmap()来创建一个单色位图,指定为1的飞机和每像素的位数,和NULL位
HBITMAP MonoBitmap = CreateBitmap(width, height, 1, 1, NULL);

查找的BITMAPINFOHEADER,位图,GetObject()的,和CreateBitmap()在MSDN。

!你可能是正确
我可能是疯
- 比利乔 -

内您就在于良好的动力性,使用它
评论会员:ceejeeb 时间:2011/12/07
确定为我的生活我不能似乎得到这个工作,你可以看看我的代码,看看什么错误:

这是我的代码放入一个HBITMAP
我的位阵列
HDC image1Dc = CreateCompatibleDC(HDC);
HBITMAP btmpNew = CreateCompatibleBitmap(HDC,pVih -> bmiHeader.biWidth,pVih - > bmiHeader.biHeight);
HBITMAP btmpNewTemp =(HBITMAP)选择对象(image1Dc,btmpNew)SetDIBits(
image1Dc,
btmpNew,
0,
pVih> bmiHeader.biHeight,
cb.pBuffer,
(BITMAPINFO *)pVih -> bmiHeader,
DIB_RGB_COLORS


宽度= pVih -> bmiHeader.biWidth;
高度= pVih> bmiHeader.biHeight;
(btmpOld!= NULL btmpNew!= NULL)
{
CompareBitmaps(btmpOld,btmpNew)
}
然后,这是我的CompareBitmaps功能
BOOL CWebcamTestViz:CompareBitmaps(HBITMAP HBitmapLeft,HBITMAP HBitmapRight)
{

HDC的DC1 = CreateCompatibleDC(NULL)
HDC的DC2 = CreateCompatibleDC(NULL)
HDC dcNew = CreateCompatibleDC(NULL)
INT pixelCount = 0;

选择对象(DC1,HBitmapLeft);
选择对象(DC2,HBitmapRight);
HBITMAP MonoBitmap = CreateBitmap(宽度,高度,1,1,NULL);
HBITMAP MonoBitmapTemp =(HBITMAP)选择对象(dcNew,MonoBitmap)

(W = 0; W 50)
{
的BitBlt(memDC,100100,
宽度,
高度,
dcNew,0,0,SRCCOPY);
::DeleteObject(DC1);
::DeleteObject(DC2);::选择对象(dcNew,MonoBitmapTemp)

::DeleteObject(MonoBitmap);::DeleteObject(dcNew); 返回true;}
ELSE
{::DeleteObject(DC1);
::DeleteObject(DC2);::选择对象(dcNew,MonoBitmapTemp)::DeleteObject(MonoBitmap);::DeleteObject(dcNew); 返回false;}
}
Theres可能加载的错误!
评论会员:PJArends 时间:2011/12/07
我还没有通过您的代码,发现所有的错误,但您可能会发现]很有帮助。我用它所有的时间,当我做任何事情,做位图。

您可能是正确的
我可能是疯了
- 比利乔 -

在你在于良好的动力 - 使用
评论会员:!ceejeeb 时间:2011/12/07
对我管理现在比较两个位图,产生的图像来表示他们之间的分歧。我有圆顶通过GetPixel和SetPixel,但这些功能都远远慢我的目的。你知道不同的方式来比较的像素。

我已阅读,比较他们的DIB是更快,所以我创建了两个DIB和放置在单独的区议会,但我不知道如何compopare。

你能帮助吗?
评论会员:PJArends 时间:2011/12/07
GetPixel()和SetPixel很慢,不怀疑。但他们这样做的一个简单的方法。
要直接访问位图数据是很多程序员的工作,但它肯定会跑得更快。
如果你打算走这条路,你必须考虑到的位图的颜色深度。对于低于每像素16位颜色深度的位图将有一个颜色表,位图数据的索引。参见GetDIBColorTable()和SetDIBColorTable()

16,24和32位颜色深度的数据中包含的实际色彩值。要记住这些事情的位图数据的每一行是DWORD对齐。 32位是最简单的的工作,他们在每32位,是另一种颜色的DWORD对齐自动。 16位在每一行结束时将有一个虚拟的颜色值,如果位图的宽度是一个奇数,和24位连续年底将有1,2或3个空字节的位图的宽度取决于。如果你需要访问个别红,绿,蓝,每种颜色的alpha分量比你还必须考虑到色彩的面具,但只要您的图像都具有相同的颜色深度,应该没有必要。

见GetDIBits()和SetDIBits()

如果您有任何问题,你可能会得到更多和更好的答案,如果你问他们在Visual C留言板。

祝你好运!

您可能是正确的
我可能是疯
- 比利乔 -

的,在你在于良好的动力性,使用它
评论会员:RafalStruzyk 时间:2011/12/07
嘛!! ..他们用很慢 - 看看我的]应用程序。这里是我来到

注 - PJA::CBitmap和PJA:CCompatibleDC周围的HBITMAP,HDC类型的简单包装

pja::CBitmap Compare(const pja::CBitmap &Bitmap1, const pja::CBitmap &Bitmap2, int x = 0, int y = 0, COLORREF ClrSame = 0x00FFFFFF, COLORREF ClrDiff = 0x00000000);

 

pja::CBitmap Compare(const pja::CBitmap &Bitmap1,   // The first bitmap

                     const pja::CBitmap &Bitmap2,   // The second bitmap

                     int x, int y,                  // The offset of the second bitmap from the first bitmap

                     COLORREF ClrSame,              // Colour used for pixels that are the same

                     COLORREF ClrDiff)              // Colour used for pixels that are different

{

    // Sanity check

    ASSERT (x > -Bitmap2.Width() && x < Bitmap1.Width());

    ASSERT (y > -Bitmap2.Height() && y < Bitmap1.Height());

 

    if (x <= -Bitmap2.Width() || x >= Bitmap1.Width() || y <= -Bitmap2.Height() || y >= Bitmap1.Height())

    {

        return pja::CBitmap();

    }

 

    // Setup the rectangles for where stuff gets drawn

    CRect Bitmap1Rect(0, 0, Bitmap1.Width(), Bitmap1.Height());

    CRect Bitmap2Rect(0, 0, Bitmap2.Width(), Bitmap2.Height());

 

    if (x < 0)

        Bitmap1Rect.OffsetRect(-x, 0);

    else

        Bitmap2Rect.OffsetRect(x, 0);

 

    if (y < 0)

        Bitmap1Rect.OffsetRect(0, -y);

    else

        Bitmap2Rect.OffsetRect(0, y);

 

    CRect FinalRect = Bitmap1Rect | Bitmap2Rect;

    CRect CombinedRect = Bitmap1Rect & Bitmap2Rect;

 

    // Create the bitmaps needed

    pja::CBitmap FinalBitmap(NULL, FinalRect.Width(), FinalRect.Height());

    pja::CBitmap CombinedBitmap(NULL, CombinedRect.Width(), CombinedRect.Height());

    pja::CBitmap MonoBitmap(CreateBitmap(CombinedRect.Width(), CombinedRect.Height(), 1, 1, NULL));

 

    // DCs for all the bitmaps

    pja::CCompatibleDC Bitmap1DC;

    pja::CCompatibleDC Bitmap2DC;

    pja::CCompatibleDC FinalBitmapDC;

    pja::CCompatibleDC CombinedBitmapDC;

    pja::CCompatibleDC MonoBitmapDC;

 

    // Select the bitmaps into the DCs

    SelectObject(Bitmap1DC, Bitmap1);

    SelectObject(Bitmap2DC, Bitmap2);

    SelectObject(FinalBitmapDC, FinalBitmap);

    SelectObject(CombinedBitmapDC, CombinedBitmap);

    SelectObject(MonoBitmapDC, MonoBitmap);

 

    // Combine the two supplied bitmaps,

    // same pixels will be white - all others will be whatever

    BitBlt(CombinedBitmapDC,

           0, 0, CombinedRect.Width(), CombinedRect.Height(),

           Bitmap1DC,

           CombinedRect.left > Bitmap1Rect.left ? CombinedRect.left : 0,

           CombinedRect.top > Bitmap1Rect.top ? CombinedRect.top : 0,

           SRCCOPY);

 

    BitBlt(CombinedBitmapDC, 0, 0, CombinedRect.Width(), CombinedRect.Height(),

           Bitmap2DC,

           CombinedRect.left > Bitmap2Rect.left ? CombinedRect.left : 0,

           CombinedRect.top > Bitmap2Rect.top ? CombinedRect.top : 0,

           0x00990066); //DSxn ROP



    // On 32 bit bitmaps we have to reset the alpha channel to zero

    if (CombinedBitmap.BitsPixel() >= 32)

    {

        SelectObject(CombinedBitmapDC, GetStockObject(WHITE_BRUSH));

        PatBlt(CombinedBitmapDC, 0, 0, CombinedBitmap.Width(), CombinedBitmap.Height(), 0x00A000C9); // DPa ROP

    }

 

    // transfer the combined bitmap to a black and white monochrome bitmap

    // white stays white, the rest turns black

    SetBkColor(CombinedBitmapDC, 0x00FFFFFF);

    BitBlt(MonoBitmapDC, 0, 0, CombinedRect.Width(), CombinedRect.Height(), CombinedBitmapDC, 0, 0, SRCCOPY);

 

    // Fill the background of the final bitmap with our background colour

    // TODO: Change this line when this function is imported into the Image Viewer

    //FillRect(FinalBitmapDC, FinalRect, CBrush(reinterpret_cast<COLORREF>(AfxGetMainWnd()->SendMessage(WMU_GETBGCOLOUR, 0, 0);

    FillRect(FinalBitmapDC, FinalRect, CBrush(RGB(236, 233, 216)));

 

    // Draw our two bitmaps

    if (FinalRect != CombinedRect)

    {

        BitBlt(FinalBitmapDC, Bitmap1Rect.left, Bitmap1Rect.top, Bitmap1Rect.Width(), Bitmap1Rect.Height(), Bitmap1DC, 0, 0, SRCCOPY);

        BitBlt(FinalBitmapDC, Bitmap2Rect.left, Bitmap2Rect.top, Bitmap2Rect.Width(), Bitmap2Rect.Height(), Bitmap2DC, 0, 0, SRCCOPY);

    }

 

    // Draw the differences using the supplied colours

    SetBkColor(FinalBitmapDC, ClrSame);

    SetTextColor(FinalBitmapDC, ClrDiff);

    BitBlt(FinalBitmapDC, CombinedRect.left, CombinedRect.top, CombinedRect.Width(), CombinedRect.Height(), MonoBitmapDC, 0, 0, SRCCOPY);

 

    return FinalBitmap;

}


您可能是正确的
我可能是疯
- 比利乔 -

内您就在于良好的动力性,用它
评论会员:IntVestor 时间:2011/12/07
文章!!伟大的,但让我们想象两个单不同的像素每一个位图。功能将虚假的,即使他们obviosly类似。因此,比较实际的像素数据时,可以添加一些错误的水平(%在第三个变量传递)。
这可能是有用的的比较时,用不同的压缩率图像 - 一些有损格式
。猜测,将更有用武之地。

又一次伟大的文章。
评论会员:PJArends 时间:2011/12/07
真实的,但如果两个位图是由一个单一的像素不同,那么他们的定义不等于。我的问题,这是我需要的东西,我需要知道,如果他们是不同的,不只是相似。一个是陷入相当复杂的领土,当它来检查图像之间的相似性。整个产业的基础上诸如此类的东西。
IntVestor写道:又一次伟大的文章。
感谢{S1}

你可能是正确
我可能是疯了
- 比利乔 -

在你所在功率
评论会员:LamprosG 时间:2011/12/07
这是什么好,用它
!的PSNR计算..所有关于
它会告诉你,如果两个图像是完全一样的,如果没有,他们是多么的不同。