Get lots of pixels colors

Apr 20, 2010 at 3:26pm
The problem is, I want to get many pixels colors in a short time. I used GetPixel but it is very slow. I tried to read about BitBlt, GetBIB, etc. But I just dont understand, how to get pixels colors then.

The part of code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct Taskas
{
	int r,
	    g,
	    b;
} T[_MaxX][_MaxY];

---------------------------------------------

        int rgb;
	int x, y;		

	HDC hdc_ = GetDC(GetDesktopWindow()) ; 	

	for(y = _Y; y <= _MaxY; y+=_Lang)
	{
		for(x = _X; x <= _MaxX; x+=_Lang)
		{
			rgb = GetPixel(hdc_, x, y);				
			T[x][y].r = GetRValue(rgb);				
		        T[x][y].g = GetGValue(rgb);
			T[x][y].b = GetBValue(rgb);			
		}	
	}		

----------------------------------------------


I just need to make it faster...
Last edited on Apr 20, 2010 at 6:04pm
Apr 22, 2010 at 12:04pm
I made sth:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
void ScanToArray()
{
HBITMAP bmp_copy;
BITMAPINFO bi;
typedef RGBQUAD *pBGR;
pBGR buf;

HDC sr, sr_copy; 
sr=GetDC(GetDesktopWindow()); 
sr_copy=CreateCompatibleDC(sr);
bmp_copy= CreateCompatibleBitmap(sr, _MaxX, _MaxY);

SelectObject(sr_copy, bmp_copy);
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = _MaxX;
bi.bmiHeader.biHeight = _MaxY;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = _MaxX * _MaxY * 4 ;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0; 

BitBlt(sr_copy, 0, 0, _MaxX, _MaxY, sr, 0, 0, SRCCOPY);
buf = (pBGR) malloc(_MaxX * _MaxY * 4);
GetDIBits(sr_copy, bmp_copy, 0, _MaxY, buf, &bi, NULL); 

for (int y = _Y; y < _MaxY; y += _Lang)
{
for (int x = _X; x < _MaxX; x += _Lang)
{ 
T[x][y].r = buf[x].rgbRed; 
T[x][y].g = buf[x].rgbGreen;
T[x][y].b = buf[x].rgbBlue;
cout << T[x][y].r << " " << T[x][y].g << " " << T[x][y].b << endl;
}
buf += _MaxX;
}
//free(buf);
}


But the colors gets wrong. http://www.codeguru.com/forum/archive/index.php/t-352792.html there the author said, that he had the same problem and he said he fixed it. But I dont understand how to... So whats wrong?
Last edited on Apr 22, 2010 at 12:25pm
Apr 22, 2010 at 10:35pm
Ive done this before and its hard work to get it to work without having an inverted array and without any memory leaks, or some other issue, but here you go;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
int ScreenX = GetDeviceCaps(GetDC(0), HORZRES);
int ScreenY = GetDeviceCaps(GetDC(0), VERTRES);
BYTE* ScreenData = new BYTE[3*ScreenX*ScreenY];

void ScreenCap
{
    HDC hdc = GetDC(NULL), hdcMem = CreateCompatibleDC (hdc);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdc, ScreenX, ScreenY);
    BITMAPINFOHEADER bmi = {0};
    bmi.biSize = sizeof(BITMAPINFOHEADER);
    bmi.biPlanes = 1;
    bmi.biBitCount = 24;
    bmi.biWidth = ScreenX;
    bmi.biHeight = -ScreenY;
    bmi.biCompression = BI_RGB;
    SelectObject(hdcMem, hBitmap);
    BitBlt(hdcMem, 0, 0, ScreenX, ScreenY, hdc, 0, 0, SRCCOPY);

    GetDIBits(hdc, hBitmap, 0, ScreenY, ScreenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
    DeleteObject(hBitmap);
    DeleteDC(hdcMem);
    ReleaseDC(NULL, hdc);
}


inline int PosR(int x, int y)
{
    return ScreenData[3*((y*ScreenX)+x)+2];
}

inline int PosG(int x, int y)
{
    return ScreenData[3*((y*ScreenX)+x)+1];
}

inline int PosB(int x, int y)
{
    return ScreenData[3*((y*ScreenX)+x)];
}

Note
bmi.biHeight = -ScreenY;
For some reason, when you GetDIBits, the buffer is inverted(horizontal and vertical i think, you can use SetPixel to check this.), and for some reason, when you use a negative height, this doesnt happen, but instread RGB becomes BGR(obiously the Pos_ functions are made so they return the correct value)

thats how it works lol.. have fun.
Last edited on Apr 22, 2010 at 10:49pm
Apr 23, 2010 at 4:09pm
Thx You very mutch :) It works!
Topic archived. No new replies allowed.