3

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?

JBentley
  • 6,099
  • 5
  • 37
  • 72
  • Note that you should select `screenshot` back out of `captureDC` before deleting `captureDC`. You should also delete `screenshot` with `DeleteObject`. – Adrian McCarthy Mar 22 '13 at 17:18
  • 4
    You cannot create `HBITMAP` on top of existing memory block. You can, however, create a bitmap using `CreateDIBSection` and obtain a raw pointer into its underlying memory block for further `memcpy` copying. You might also want to look at `GetDIBits` for getting DC data into memory block. – Roman R. Mar 22 '13 at 17:20
  • CreateDibSection give you access to the memory buffer. Not easy to use at first. Here some sample that may help you http://www.codeproject.com/Articles/2841/How-to-replace-a-color-in-a-HBITMAP – ColdCat Feb 24 '15 at 21:17

0 Answers0