I am using the FreeImage library to store and manipulate bitmap data. Part of my code requires me to take a screenshot of a window (in Windows), and store it as a FBITMAP*
(FreeImage's bitmap data structure). The method I have worked out of doing this involves two steps: capture the image, then convert it to a FBITMAP*
.
To capture the image, I do something like this:
HWND window; // Assume this is a valid handle to my window
int width; // width of window client area
int height; // height of window client area
HDC windowDC = GetDC(window);
HDC captureDC = CreateCompatibleDC(windowDC);
HBITMAP screenshot = CreateCompatibleBitmap(windowDC, width, height);
SelectObject(captureDC, screenshot);
BitBlt(captureDC, 0, 0, width, height,
captureDC, 0, 0, SRCCOPY|CAPTUREBLT);
ReleaseDC(window, windowDC);
DeleteDC(captureDC);
FreeImage provides a function which returns a raw pointer to the pixel data:
BYTE* FreeImage_GetBits(FBITMAP*)
The FAQ explains that a HBITMAP
(WinAPI handle to a bitmap) can be converted to a FBITMAP*
using GetDIBits
, which takes a source HBITMAP
and a destination raw pointer as arguments, and copies the pixel data from one to the other.
The problem with this approach is that I have copied the data twice - once in the BitBlt
from the window DC to the HBITMAP
selected in the memory DC, and then again from the HBITMAP
to the FreeImage memory buffer. I wish to remove this inefficiency and copy the data directly to my raw pointer in the BitBlt
operation. For this to work, I need a memory DC which has a HBITMAP
selected into it, and where that HBITMAP
points to my memory buffer instead of to memory that Windows allocated for it.
How can I achieve this?