MFC
2009.03.23 11:23

비트맵 비교

조회 수 41068 댓글 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
번호 분류 제목 날짜 조회 수 추천 수
56 Pi Teensy 3.5 spec & pin 2017.07.12 5027 0
55 PHP [PHP] .php 확장자 없이 URL 접속하기 2020.10.26 4827 0
54 Android 안드로이드 국가별 언어코드 2020.10.06 4729 0
53 일반 Cakewalk 단축키 정리 2021.07.20 4154 0
52 LINUX Ubuntu apt-get 명령어 정리 2020.02.11 4119 0
51 C# C#의 $으로 문자열 보간하기 2022.04.28 4047 0
50 Pi 레귤레이터(3.3V 1A) KA78R33 데이터시트 file 2019.08.20 3943 0
49 Android Android Studio 안드로이드 스튜디오 단축키 2020.03.16 3690 0
48 Android Android Animation XML 사용 2020.12.01 3648 0
47 C# C# ?? 및 ??=, ?. 연산자 2021.05.09 3288 0
46 일반 엑셀 Excel 데이터 시각화 (엑셀 사용 Tip) 2021.08.25 2937 0
45 일반 3D프린트 가이드 모음 2022.04.02 2473 0
44 업무 Back-End 관련 정보 2022.05.17 1775 0
43 PHP SQL :: EXIST , NOT EXIST 2022.09.05 1633 0
42 HTML5 typescript 기본문법 정리 2023.01.13 1517 0
목록
Board Pagination ‹ Prev 1 ... 26 27 28 29 30 31 32 33 34 Next ›
/ 34

나눔글꼴 설치 안내


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

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

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5