MFC
2009.03.23 11:23

비트맵 비교

조회 수 41353 댓글 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 일반 마크다운 markdown (.md) 파일이란 2017.07.12 12871 0
415 Pi 아두이노 (Arduino)로 서보모터 (SG90) 제어 2017.07.11 11524 0
414 일반 배치파일(bat)에서 명령 실행결과를 변수에 저장하는 방법 2017.07.05 19605 0
413 LINUX 프로세스를 이름으로 단번에 종료하기 2017.06.07 9345 0
412 C++ istringstream 을 이용한 string type 변환 & 토크나이징 2017.06.07 9222 0
411 LINUX bluetooth on Ubuntu 2017.05.25 14065 0
410 Pi Raspberry pi 에 Bluetooth사용을 위한 bluez설치 및 실행 2017.05.24 10314 0
409 LINUX 블루투스 사용하기 hci tool 2017.05.24 12480 0
408 일반 BT와 BLE 2017.05.16 7220 0
407 LINUX [Shell Script] Bash 파일 유무 체크하는 방법과 파일 존재 검사 옵션 2017.05.16 21939 0
406 LINUX [Shell Script] Bash 실행결과를 변수에 담기 2017.05.16 13940 0
405 Pi SSD1306 OLED Displays with Raspberry Pi 2017.05.10 7257 0
404 Pi SPI란? (Serial Peripheral Interface) 2017.04.20 16097 0
403 Pi LCD interface 종류 및 Driver IC 2017.04.17 6904 0
402 Pi 아두이노의 인터럽트 (interrupt) 사용 2017.04.13 14972 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