В КОНЦЕ ВОПРОСА МОЕ ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ
Привет всем, я должен реализовать функцию, которая сравнивает два снимка части экрана, чтобы узнать, есть ли различия / различия.Я написал что-то вроде следующего кода, но я не могу заставить его работать.В коде 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])
никогда не будет выполнена.Я не знаю, является ли это правильным способом для сравнения двух растровых изображений (преобразованных в массивы символов).Я гуглил и искал в 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);
}
Спасибо
Франческо
Ps.Объявления переменных помещаются рядом с блоком, на который они ссылаются, только для достижения большей ясности в этом вопросе.
РЕДАКТИРОВАТЬ:
Я переписал это так, и это похоже на работу :) Спасибо всемОднако любая коррекция приветствуется
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);
}