MFC
2009.03.23 11:23

비트맵 비교

조회 수 40927 댓글 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
번호 분류 제목 날짜 조회 수 추천 수
416 C 삽입정렬 Insertion Sort file 2005.08.10 32955 0
415 LINUX 삼바(SAMBA)를 이용한 윈도우 접근 가능 공유폴더 만들기 2016.02.23 17883 0
414 일반 사용하지 않는 COM Port 삭제하기 2015.03.18 9227 0
413 C# 사용자 정의 이벤트(event) 예제 2013.08.08 11849 0
412 LINUX 사용자 계정 목록 보기 2013.04.22 16007 0
» MFC 비트맵 비교 2009.03.23 40927 0
410 LINUX 블루투스 사용하기 hci tool 2017.05.24 11909 0
409 개념 블루투스 버전별 차이 1 2012.08.23 40739 0
408 Pi 브라우저로 gpio 제어, WebIOPi 2017.10.17 43638 0
407 Pi 부품 구매 2016.11.15 5988 0
406 C 병합 정렬 Merge Sort file 2005.08.10 35221 0
405 C# 변경된 파일을 감시하는 루틴 2013.10.30 12538 0
404 일반 범용 레지 스터(eax, ebx, ecx, edx, esi, edi, esp, ebp) 2019.06.03 9903 0
403 일반 배치파일(bat)에서 명령 실행결과를 변수에 저장하는 방법 2017.07.05 19002 0
402 일반 배치파일(bat)에서 날짜-시간을 파일 명으로 쓰기 2014.10.10 29292 0
목록
Board Pagination ‹ Prev 1 2 3 4 5 6 7 8 9 10 11 ... 34 Next ›
/ 34

나눔글꼴 설치 안내


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

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

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5