MFC
2009.03.23 11:23

비트맵 비교

조회 수 40813 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print

Table of Contents

  1. Substraction
  2. 화면을 캡쳐하여 지정된 영역과 파일에서 읽어온 비트맵과 비교


Substraction  

우선 비트맵 두개를 비교한다는 것이 XOR 연산을 통하여 보는 것보다. 영상처리의 Subtraction을 이용하는 것이 더욱 속도도 빠르고, 정확한 결과를 얻을 수 있을 것 같습니다.

우선 두개의 비트맵 또는 이미지 파일의 원본 버퍼를 읽어서, (두개의 사이즈가 같다고 가정하고) Subtraction을 수행합니다. 간단한 코드를 예제로 해보겠습니다.

void Subtraction(int nWidth, nHeight, void* pSrcA, void* pSrcB, /*out*/void *pDst)
{
    for(register int y = 0; y < nHeight; ++y)
        for(register int x = 0; x < nWidth; ++x)
            pDst[y * nWidth + x] = pSrcA[y * nWidth + x] - pSrcB[y * nWidth + x];
}

nWidth, nHeight는 영상의 크기를 나타내며, pSrcA와 pSrcB는 원본 비트맵의 버퍼입니다.

결과는 pDst에 저장되며, pDst를 버퍼로하는 비트맵을 만들어서 화면에 출력하게 되면, A 영상과 B 영상의 차이점을 확인할 수가 있습니다.

위 소스는 테스트되지 않았습니다.


화면을 캡쳐하여 지정된 영역과 파일에서 읽어온 비트맵과 비교  

/*
   > Function: CheckBmp
   > Parameters:
          szFileName: 비트맵 파일명
          rRect: 캡쳐할 영역
*/
BOOL CheckBmp(LPTSTR szFileName, CRect &rRect)
{
        int      x,y;
        int      dx,dy;
        CDC      memDC;
        CDC      ScreenDC;
        CBitmap  m_Bitmap;
        CPalette m_Pal;

        x = rRect.TopLeft().x;
        y = rRect.TopLeft().y;
        dx = rRect.Width();
        dy = rRect.Height();
        ScreenDC.CreateDC("DISPLAY",  NULLNULLNULL);                         //스크린 DC를 얻는다.
        memDC.CreateCompatibleDC(&ScreenDC);                                        //스크린 DC와 호환되는 DC 를 만든다
        m_Bitmap.CreateCompatibleBitmap(&ScreenDC, dx, dy);                     //스크린 DC와 호환되는 비트맵을 만든다.
        CBitmap* pOldBitmap = memDC.SelectObject(&m_Bitmap);
        memDC.StretchBlt(00, dx, dy, &ScreenDC, x, y, dx, dy, SRCCOPY);
        //현재 해상도가 256칼라 이하라면 팔레트 추가
        if( ScreenDC.GetDeviceCaps(RASTERCAPS) & RC_PALETTE ) {
                UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
                LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
                pLP->palVersion = 0x300;
                pLP->palNumEntries = GetSystemPaletteEntries(
                                                                  ScreenDC,
                                                                  0,
                                                                  255,
                                                                  pLP->palPalEntry );
                // Create the palette
                m_Pal.CreatePalette( pLP );
                delete[] pLP;
        }
        memDC.SelectObject(pOldBitmap);
        HANDLE hDIB = DDBToDIB(m_Bitmap, BI_RGB, &m_Pal);
        ScreenDC.DeleteDC();
        if (hDIB == NULL) {
                return FALSE;
        }

        if ( TRUE == CompDIB(szFileName, hDIB) )  {      //이미지 비교
                GlobalFree(hDIB);
                return TRUE;
        } else {
                GlobalFree(hDIB);
                return FALSE;
        }
}

// 주어진 파일명의 비트맵과 동일한 비트맵인가를 비교.
BOOL CompDIB(LPTSTR szFileName, HANDLE hDIB)
{
        BITMAPFILEHEADER      hdr;
        LPBITMAPINFOHEADER    lpbi;
        unsigned char *pBuf;
        long lBmpSize;

        if (!hDIB)
                return FALSE;

        CFile file;

        if (!file.Open(szFileName, CFile::modeRead)) return FALSE;

        lpbi = (LPBITMAPINFOHEADER)hDIB;

        // 한 픽셀당 비트수를 왼쪽으로 1 이동 (shift)

        int nColors = 1 << lpbi->biBitCount;

        lBmpSize = GlobalSize(hDIB);
        if(lBmpSize <= BMP_FRONT_GARBAGE_SIZE) {
                return FALSE;
        }

        // Fill in the fields of the file header ( Bitmap file header )
        hdr.bfType        = ((WORD) ('M' << 8) | 'B');         // is always "BM"   
        hdr.bfSize        = lBmpSize + sizeof(hdr);              // 비트맵 파일의 전체 크기
        hdr.bfReserved1   = 0;
        hdr.bfReserved2   = 0;

        // 파일에서 비트맵 데이터가 있는 위치
        hdr.bfOffBits = (DWORD) (sizeof(hdr)) + lpbi->biSize;

        //준비
        pBuf = (unsigned char *)malloc(lBmpSize-BMP_FRONT_GARBAGE_SIZE);        //대충 큼직하게
        file.Seek(sizeof(hdr)+BMP_FRONT_GARBAGE_SIZE, CFile::begin);                   //헤더랑 파레트는 뛴다.
        file.Read(pBuf, lBmpSize- BMP_FRONT_GARBAGE_SIZE );

        //DIB header and the bits 비교
        if ( 0 != memcmp(pBuf, (char *)lpbi+BMP_FRONT_GARBAGE_SIZE, lBmpSize- BMP_FRONT_GARBAGE_SIZE ) ) {
                free(pBuf);
                file.Close();
                return FALSE;
        }
        free(pBuf);
        file.Close();
        return TRUE;
}

 

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5