2011-06-05 104 views
2

的字節在問題我上次編輯如何字節比較在C++兩幅位截圖

大家好, 我要實現的是,爲了兩槍比較屏幕的一部分的功能END瞭解是否有差異/變化。我寫了類似下面的代碼,但我無法管理它的工作。在代碼COORDINATES_RECT是一個結構

typedef struct _COORDINATES_RECT { 
int  x; 
int  y; 
int  sizeX; 
int  sizeY; 
} COORDINATES_RECT; 

,在輸入保持數據知道哪個是分析在屏幕的部分,並且在輸出返回,其中所述功能發現變化最大的矩形的數據。爲了更好地解釋問題,我看到如果最終構建:

if(lpbitmap1[(i*bmpScreen1.bmWidth)+j] != lpbitmap2[(i*bmpScreen1.bmWidth)+j]) 

永遠不會被執行。我不知道這是否是比較兩個位圖(轉換爲char數組)的正確方法。我用Google搜索並搜索了msdn,但沒有結果。 的完整代碼如下:

void testBitmapVariations(COORDINATES_RECT *c) 
{ 
HDC hdcScreen = GetDC(NULL); 
HDC hdcMemDC1 = CreateCompatibleDC(hdcScreen); 
HDC hdcMemDC2 = CreateCompatibleDC(hdcScreen); 
HBITMAP hBmpScreen1 = NULL; 
HBITMAP hBmpScreen2 = NULL; 
BITMAP bmpScreen1; 
BITMAP bmpScreen2; 

if(!hdcMemDC1 || !hdcMemDC2) 
{ 
    MessageBox(NULL,L"CreateCompatibleDC failed", L"Failed", MB_OK); 
    ReleaseDC(NULL, hdcMemDC1); 
    ReleaseDC(NULL, hdcMemDC2); 
    return; 
} 
hBmpScreen1 = CreateCompatibleBitmap(hdcMemDC1, c->sizeX, c->sizeY); 
hBmpScreen2 = CreateCompatibleBitmap(hdcMemDC2, c->sizeX, c->sizeY); 

SelectObject(hdcMemDC1,hBmpScreen1); 

if(!BitBlt(hdcMemDC1, 
      0,0, 
      c->sizeX, c->sizeY, 
      hdcScreen, 
      c->x,c->y, 
      SRCCOPY)) 
{ 
    MessageBox(NULL,L"BitBlt failed", L"Failed", MB_OK); 
    ReleaseDC(NULL, hdcMemDC1); 
    ReleaseDC(NULL, hdcMemDC2); 
    return; 
} 

GetObject(hBmpScreen1,sizeof(BITMAP),&bmpScreen1); 

BITMAPFILEHEADER bmfHeader;  
BITMAPINFOHEADER bi; 

bi.biSize = sizeof(BITMAPINFOHEADER);  
bi.biWidth = bmpScreen1.bmWidth;  
bi.biHeight = bmpScreen1.bmHeight; 
bi.biPlanes = 1;  
bi.biBitCount = 32;  
bi.biCompression = BI_RGB;  
bi.biSizeImage = 0; 
bi.biXPelsPerMeter = 0;  
bi.biYPelsPerMeter = 0;  
bi.biClrUsed = 0;  
bi.biClrImportant = 0; 

DWORD dwBmpSize = ((bmpScreen1.bmWidth * bi.biBitCount + 31)/32) * 4 * bmpScreen1.bmHeight; 

// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that 
// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc 
// have greater overhead than HeapAlloc. 
char *lpbitmap1 = (char *)malloc(dwBmpSize);  

// Gets the "bits" from the bitmap and copies them into a buffer 
// which is pointed to by lpbitmap1. 
GetDIBits(hdcScreen, hBmpScreen1, 0, 
    (UINT)bmpScreen1.bmHeight, 
    lpbitmap1, 
    (BITMAPINFO *)&bi, DIB_RGB_COLORS); 

Sleep(200); 

SelectObject(hdcMemDC2,hBmpScreen2); 

if(!BitBlt(hdcMemDC2, 
      0,0, 
      c->sizeX, c->sizeY, 
      hdcScreen, 
      c->x,c->y, 
      SRCCOPY)) 
{ 
    MessageBox(NULL,L"BitBlt failed", L"Failed", MB_OK); 
    ReleaseDC(NULL, hdcMemDC1); 
    ReleaseDC(NULL, hdcMemDC2); 
    return; 
} 

GetObject(hBmpScreen2,sizeof(BITMAP),&bmpScreen2); 

char *lpbitmap2 = (char *)malloc(dwBmpSize);  

// Gets the "bits" from the bitmap and copies them into a buffer 
// which is pointed to by lpbitmap2. 
GetDIBits(hdcScreen, hBmpScreen2, 0, 
    (UINT)bmpScreen2.bmHeight, 
    lpbitmap2, 
    (BITMAPINFO *)&bi, DIB_RGB_COLORS); 

int i, j, minX = bmpScreen1.bmWidth, minY = bmpScreen1.bmHeight, maxX = 0, maxY = 0; 
bool changed = false; 

for(i = 0; i < bmpScreen1.bmHeight; i++) 
{ 
    for(j = 0; j < bmpScreen1.bmWidth; j++) 
    { 
        // I don't know why this if never get executed 
     if(lpbitmap1[(i*bmpScreen1.bmWidth)+j] != lpbitmap2[(i*bmpScreen1.bmWidth)+j]) 
     { 
      changed = true; 

      if(i < minY) 
       minY = i; 
      if(i > maxY) 
       maxY = i; 
      if(j < minX) 
       minX = j; 
      if(j > maxY) 
       maxY = j; 
     } 
    } 
} 
if(changed) 
{ 
    c->x = minX; 
    c->y = minY; 
    c->sizeX = maxX - minX; 
    c->sizeY = maxY - minY; 
} 
else 
{ 
    c->sizeX = 0; 
    c->sizeY = 0; 
} 
//Frees from the heap 
free(lpbitmap1); 
free(lpbitmap2); 
ReleaseDC(NULL, hdcMemDC1); 
ReleaseDC(NULL, hdcMemDC2); 
} 

感謝

弗朗西斯

詩篇。變量聲明旁邊放他們指的是隻有實現在這個問題上更清晰塊..

編輯:

我重寫它這樣,它似乎工作:)感謝所有,但是,任何修正認識

void testBitmapVar(COORDINATES_RECT *c) 
{ 
HDC  screenDC = GetDC(0), 
     memDC = CreateCompatibleDC(screenDC); 
HBITMAP hBm = CreateCompatibleBitmap(screenDC, c->sizeX, c->sizeY), 
     oldHBm; 
BITMAP bm; 
BITMAPFILEHEADER bmfHeader;  
BITMAPINFOHEADER bi; 
UINT *pixels = (UINT*) malloc ((c->sizeX*c->sizeY) * sizeof(UINT)); 
std::ostringstream ss; 
std::wstring str; 
int  i, j, minX, maxX, minY, maxY; 

if(!pixels) 
{ 
    c->sizeX = 0; 
    c->sizeY = 0; 
    return; 
} 
memset(pixels, 0, (c->sizeX*c->sizeY) * sizeof(UINT)); 
oldHBm = (HBITMAP) SelectObject(memDC, hBm); 

// copies to bitmap 
BitBlt(memDC, 0, 0, c->sizeX, c->sizeY, screenDC, c->x, c->y, SRCCOPY); 

Sleep(500); 

BitBlt(memDC, 0, 0, c->sizeX, c->sizeY, screenDC, c->x, c->y, SRCINVERT); 
GetObject(hBm, sizeof(BITMAP), &bm); 

bi.biSize = sizeof(BITMAPINFOHEADER);  
bi.biWidth = bm.bmWidth;  
bi.biHeight = bm.bmHeight; 
bi.biPlanes = 1;  
bi.biBitCount = 32;  
bi.biCompression = BI_RGB;  
bi.biSizeImage = 0; 
bi.biXPelsPerMeter = 0;  
bi.biYPelsPerMeter = 0;  
bi.biClrUsed = 0;  
bi.biClrImportant = 0; 

GetDIBits(memDC, hBm, 0, 
    (UINT)bm.bmHeight, 
    pixels, 
    (BITMAPINFO *)&bi, DIB_RGB_COLORS); 

for(i = 0, minY = c->sizeY, maxY = -1; i < c->sizeY; i++) 
{ 
    for(j = 0, minX = c->sizeX, maxX = -1; j < c->sizeX; j++) 
    { 
     if(pixels[(i*c->sizeX)+j]) 
     { 
      if(i < minY) 
       minY = i; 
      if(i > maxY) 
       maxY = i; 
      if(j < minX) 
       minX = j; 
      if(j > maxX) 
       maxX = j; 
     } 
    } 
} 
if(maxX != -1 && maxY != -1) 
{ 
    c->x = minX; 
    c->y = minY; 
    c->sizeX = maxX - minX; 
    c->sizeY = maxY - minY; 
} 
else 
{ 
    c->sizeX = 0; 
    c->sizeY = 0; 
} 

free(pixels); 
SelectObject(memDC, oldHBm); 
DeleteObject(hBm); 
ReleaseDC(0, screenDC); 
DeleteDC(memDC); 
} 
+0

你應該描述你不喜歡的程序中的哪個缺陷。 – 2011-06-05 13:47:58

+0

正如我之前所說的「我無法管理它的工作」..它無法找到第一個200毫秒後拍攝的兩個屏幕截圖的變體.. – gc5 2011-06-05 14:30:54

+0

你嘗試檢查這些位圖是否被正確捕獲? – Ali1S232 2011-06-05 16:56:41

回答

4

而不是完全靠自己比較兩個位圖,可以考慮使用的BitBlt使用SRCINVERT運營商,異或兩個一起把它們結合在一起,使相同的部件將顯示爲零,並所有的非零區域都會有差異。

+1

謝謝..我會盡力讓你知道:) – gc5 2011-06-05 16:33:14