1

I want to use GetDIBits to load a bitmap in C++. Here's the code I'm using:

HBITMAP hBmp = LoadBitmap(hInstance, MAKEINTRESOURCE(id));

BITMAP BM;
GetObject(hBmp, sizeof(BM), &BM);

GLvoid* bits = NULL;

BITMAPINFO bitmap_info;
        memset(&bitmap_info, 0, sizeof(bitmap_info));
        bitmap_info.bmiHeader.biSize = sizeof(bitmap_info.bmiHeader);
        bitmap_info.bmiHeader.biWidth  = BM.bmWidth;
        bitmap_info.bmiHeader.biHeight = BM.bmHeight;
        bitmap_info.bmiHeader.biPlanes = 1;
        bitmap_info.bmiHeader.biBitCount = DM_BITSPERPEL;//bits per pixel
        bitmap_info.bmiHeader.biCompression = BI_RGB;

GetDIBits(device_context,
            hBmp,
            0, BM.bmWidth,
            bits,
            &bitmap_info,
            DIB_RGB_COLORS);

But it seems that bits is NULL for some reason. Is there something wrong in my code? I used GetBitmapBits before, bits wasn't NULL then.

user3075425
  • 332
  • 1
  • 6
  • 23

1 Answers1

3

The behaviour you are encountering is exactly as defined:

lpvBits [out]

A pointer to a buffer to receive the bitmap data. If this parameter is NULL, the function passes the dimensions and format of the bitmap to the BITMAPINFO structure pointed to by the lpbi parameter.

(Source: MSDN)

To summarize, you have to provide a non-zero pointer if you want GetDIBits() to fill in the bits. It is your responsibility to allocate the required memory.

ph4nt0m
  • 948
  • 4
  • 10
  • 23
  • I fixxed it by using `GLvoid* bits = malloc(BM.bmWidth * BM.bmHeight * sizeof(DWORD));`, but now `GetDIBits` returns 0. So I think I did something different wrong too? – user3075425 Apr 26 '14 at 17:49
  • @user3075425 There is a lot that could be wrong, and it is not easy to tell without further code. One thing that doesn't look right though is the number of scan lines (4th paramter of `GetDIBits()`) which should be `BM.bmHeight`. Please check if `LoadBitmap()` and `GetObject()` succeed and make sure that your `device_context` is valid. You could also let `GetDIBits()` fill the `BITMAPINFO` structure (by calling it with an empty pointer first) instead of doing so manually. – ph4nt0m Apr 26 '14 at 18:12
  • What would be the best way to check if `LoadBitmap` success? And could you explain whats with `GetObject()`, I havn't used this function in my code – user3075425 Apr 26 '14 at 18:18
  • @user3075425 Please see [MSDN](http://msdn.microsoft.com/en-us/library/windows/desktop/dd145033%28v=vs.85%29.aspx). `LoadBitmap()` will return `NULL` if something went wrong. You are using `GetObject()` in the fourth line of your code, so I don't know why you are trying to deny that. ;) – ph4nt0m Apr 26 '14 at 18:28
  • Everything seems to be working until `GetDIBits`. Is there maybe something wrong with the `BITMAPINFO`? – user3075425 Apr 26 '14 at 18:45
  • @user3075425 Since I don't know the bitmap you are trying to load, I can't tell you for sure. But as I suggested, please try to let `GetDIBits()` fill your `BITMAPINFO` structure by calling it with `bits = NULL` first. After that, you can call `GetDIBits()` again (this time **with** memory allocted) to get the actual data. Furthermore, please have a look at [this question](http://stackoverflow.com/questions/16991370/c-getdibits-not-working), I think it covers exactly what you want to achieve. – ph4nt0m Apr 26 '14 at 19:38