MFC
2009.03.23 11:23

비트맵 비교

조회 수 41034 댓글 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;
}

 

Dreamy의 코드 스크랩

내가 모으고 내가 보는

List of Articles
번호 분류 제목 날짜 조회 수 추천 수
461 LINUX gdb 쓸때 상용구 secret 2019.06.26 0 0
460 Pi 라즈베리파이 내 작업 명령 secret 2019.06.10 0 0
459 일반 범용 레지 스터(eax, ebx, ecx, edx, esi, edi, esp, ebp) 2019.06.03 10099 0
458 Python 디렉토리 없으면 만들기 2019.03.30 6096 0
457 Python 줄 바꿈 없이 출력하는 방법 2019.03.30 7159 0
456 LINUX Ubuntu에서 Python 버전을 변경하는 방법 2019.03.29 12369 0
455 Python Google Colab에서 파일 업로드/다운로드 팁 2019.03.06 36737 0
454 Python pandas, matplot 자주사용하는 코드 2019.03.06 5143 0
453 Python matplot에서 한글이 보이도록 하는 코드 2019.03.06 6334 0
452 일반 OMV (OpenMediaVault) 플러그인들 2019.02.10 8191 0
451 일반 ddns 정보 secret 2019.02.10 0 0
450 Android git archive 를 사용해서 폴더를 .git 제외하고 tar 나 zip 으로 묶기 1 2019.02.10 7407 0
449 LINUX vi 설정하기(.vimrc) 2019.02.01 5664 0
448 Pi 칩 저항 사이즈표, 사이즈변환, 와트, 오차표 2019.01.11 10721 0
447 Pi NPN과 PNP 트랜지스터의 차이 2019.01.03 14093 0
목록
Board Pagination ‹ Prev 1 2 3 4 5 6 7 8 9 10 ... 34 Next ›
/ 34

나눔글꼴 설치 안내


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

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

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5