Apart from the good answers already given, here's an example of how to get a simple array structure to walk on. (You can use e.g. Goz' code for the iteration.)
GetDIBits reference @ MSDN
You have to select DIB_RGB_COLORS
as flag for uUsage
and set up the BITMAPINFO
structure and the BITMAPINFOHEADER
structure it contains. When you set biClrUsed
and biClrImportant
to zero, there is "no" color table, so you can read the pixels of the bitmap you get from GetDIBits
as a sequence of RGB values. Using 32
as bit count (biBitCount
) sets up the data structure according to MSDN:
The bitmap has a maximum of 2^32 colors. If the biCompression
member of the BITMAPINFOHEADER
is BI_RGB
, the bmiColors
member of BITMAPINFO
is NULL
. Each DWORD
in the bitmap array represents the relative intensities of blue, green, and red, respectively, for a pixel. The high byte in each DWORD
is not used.
Since a MS LONG
is exactly 32 bit long (the size of a DWORD
), you do not have to pay attention to padding (as described in the Remarks section).
Code:
HDC hdcSource = NULL; // the source device context
HBITMAP hSource = NULL; // the bitmap selected into the device context
BITMAPINFO MyBMInfo = {0};
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
// Get the BITMAPINFO structure from the bitmap
if(0 == GetDIBits(hdcSource, hSource, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS))
{
// error handling
}
// create the pixel buffer
BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];
// We'll change the received BITMAPINFOHEADER to request the data in a
// 32 bit RGB format (and not upside-down) so that we can iterate over
// the pixels easily.
// requesting a 32 bit image means that no stride/padding will be necessary,
// although it always contains an (possibly unused) alpha channel
MyBMInfo.bmiHeader.biBitCount = 32;
MyBMInfo.bmiHeader.biCompression = BI_RGB; // no compression -> easier to use
// correct the bottom-up ordering of lines (abs is in cstdblib and stdlib.h)
MyBMInfo.bmiHeader.biHeight = abs(MyBMInfo.bmiHeader.biHeight);
// Call GetDIBits a second time, this time to (format and) store the actual
// bitmap data (the "pixels") in the buffer lpPixels
if(0 == GetDIBits(hdcSource, hSource, 0, MyBMInfo.bmiHeader.biHeight,
lpPixels, &MyBMInfo, DIB_RGB_COLORS))
{
// error handling
}
// clean up: deselect bitmap from device context, close handles, delete buffer