댓글 쓰기 권한이 없습니다. 로그인 하시겠습니까?
MFC
2009.03.23 11:23
비트맵 비교
조회 수 43096 댓글 0
Table of Contents
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", NULL, NULL, NULL); //스크린 DC를 얻는다. memDC.CreateCompatibleDC(&ScreenDC); //스크린 DC와 호환되는 DC 를 만든다 m_Bitmap.CreateCompatibleBitmap(&ScreenDC, dx, dy); //스크린 DC와 호환되는 비트맵을 만든다. CBitmap* pOldBitmap = memDC.SelectObject(&m_Bitmap); memDC.StretchBlt(0, 0, 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의 코드 스크랩내가 모으고 내가 보는
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Designed by sketchbooks.co.kr / sketchbook5 board skin
Sketchbook5, 스케치북5
Sketchbook5, 스케치북5
Sketchbook5, 스케치북5
Sketchbook5, 스케치북5