With device independent bitmap (DIB) Windows allows to access bitmap pixels directly.
I was wondering how I can get an array of pixels of a given bitmap with Win32 API GDI functions to perform some image proceessing like simple decreasing of image brightness.
My goal was to access a bitmap of existing desktop window and fade all pixels a little.
First create a DIB:
unsigned __int32 * pBuffer; BITMAPINFO DibInfo; //uiWidth and uiHeight are set appropriately DibInfo.bmiHeader.biWidth = uiWidth; DibInfo.bmiHeader.biHeight = uiHeight; DibInfo.bmiHeader.biPlanes = 1; // 32 bits per pixel // were mapped as 0x00RRGGBB DibInfo.bmiHeader.biBitCount = 32; //no compression DibInfo.bmiHeader.biCompression = BI_RGB; //size is not set initially, that's ok for this call DibInfo.bmiHeader.biSizeImage = 0; //for 72DPI resolution DibInfo.bmiHeader.biXPelsPerMeter = 2834; DibInfo.bmiHeader.biYPelsPerMeter = 2834; DibInfo.bmiHeader.biClrUsed = 0; DibInfo.bmiHeader.biClrImportant = 0; //this is mandatory DibInfo.bmiHeader.biSize = sizeof(DibInfo.bmiHeader); //create DIB using display or window DC //note, that after this call pBuffer will contain a pointer to the allocated //memory reserved for DIB pixels hDIB = CreateDIBSection(hDC, &DibInfo, DIB_RGB_COLORS, &pBuffer, NULL, 0); //copy DDB bitmap pixels to DIB buffer at pBuffer //this function allows to specify compression mechanism //but I use plain uncompressed format now GetDIBits(hDC, hSourceBitmap, 0, uiHeight, pBuffer, &DibInfo, DIB_RGB_COLORS);
In the code above there were two parameters called biXPelsPerMeter and biYPelsPerMeter.
For a common 72DPI resolution I calculated the value 2834 in this was:
there are (100 cm / 2.54 cm) = 39.3700... inches in one centimeter for 72dpi resolution we need to calculate 39.3700 inches * 72 dpi = 2834 dots per meter
Now accessing pixels is straightforward:
DWORD iNumberOfPixels = uiHeight * uiWidth;
//lower brightness substantially
for(i=0;i<inumberofpixels ;i++){
pBuffer[i] = (pBuffer[i] >> 3) & ~0x00E0E0E0;
}
And finally it is needed to copy pixels back from DIB to DDB.
SetDIBits(hDC, hSourceBitmap, 0, uiHeight, pBuffer, &DibInfo, DIB_RGB_COLORS);
There is a faster method in Windows, which was designed to provide a faster way to access displayed pixels. Look for DirectDraw documentation.