Get a HBITMAP from an 24bit BMP file loaded into memory

匿名 (未验证) 提交于 2019-12-03 09:05:37

问题:

I have a 24bit BMP file loaded into RAM and I'm trying to create a HBITMAP for this image file. I have found some examples around which I've been experimenting with, but can't seem to make work. Basically, I need a HBITMAP for the file, so that I can unload the file and just keep the HBITMAP which I can dispose of later with DeleteObject(). Since this bitmap is loaded very early on in my application, there is no application Window and therefore no HDC. This is what I have so far:-

HBITMAP cBitmap;  // This should be where my bitmap handle ends up. mem;              // This is a void* pointer to the loaded BMP file   tagBITMAPFILEHEADER bfh = *(tagBITMAPFILEHEADER*)mem; tagBITMAPINFOHEADER bih = *(tagBITMAPINFOHEADER*)(mem + sizeof(tagBITMAPFILEHEADER)); RGBQUAD rgb = *(RGBQUAD*)(mem + sizeof(tagBITMAPFILEHEADER) + sizeof(tagBITMAPINFOHEADER));  BITMAPINFO bi; bi.bmiColors[0] = rgb; bi.bmiHeader = bih;  UINT8* pixels = mem + bfh.bfOffBits; void* ppv; HBITMAP hBitmap = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &ppv, NULL, 0); SetDIBits(NULL, hBitmap, 0, bih.biHeight, pixels, &bi, DIB_RGB_COLORS); GetObject(hBitmap, sizeof(BITMAP), &cBitmap); 

For some reason that just baffles me, cBitmap ends up being NULL. And another thing that puzzles me... DIB_RGB_COLORS means that the BITMAPINFO has a pointer to literal RGB values, but how does that work with a 24bit image, which doesn't have a palette?

回答1:

Um, that's not how GetObject works. The usage is

GetObject(handle, sizeof(object), &object); 

In your case, the expectation is that you call it as

BITMAP bitmap; GetObject(hBitmap, sizeof(BITMAP), &bitmap); 

You are not passing a pointer to a BITMAP structure, so the behavior is undefined.

You don't need GetObject at all. You already have your HBITMAP. It's in the hBitmap variable.

cBitmap = hBitmap; 


回答2:

If you are loading a file from disk, it's probably easiest to use LoadImage() with the LR_LOADFROMFILE flag.

To create a HBITMAP from file data that has already been loaded into memory, you can do something similar to the following:

HBITMAP ConvertDibToHBitmap(void* bmpData) {     HBITMAP hBitmap = NULL;     BOOL success = FALSE;      // NOTE: Assumes the BITMAPFILEHEADER is present (not normally the case for     // an in-memory DIB)     LPBITMAPFILEHEADER bfh = (LPBITMAPFILEHEADER) bmpData;     LPBITMAPINFOHEADER bih = (LPBITMAPINFOHEADER) (bfh + 1);     void *pixels = (char*) (bih + 1); // NOTE: Assumes no color table (i.e., bpp >= 24)      HDC hdc = GetDC(NULL);     if (hdc != NULL) {         hBitmap = CreateCompatibleBitmap(hdc, bih->biWidth, bih->biHeight);         if (hBitmap != NULL) {             HDC hdcMem = CreateCompatibleDC(hdc);             if (hdcMem != NULL) {                 HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap);                 if (StretchDIBits(hdcMem, 0, 0, bih->biWidth, bih->biHeight,                         0, 0, bih->biWidth, bih->biHeight, pixels,                         (LPBITMAPINFO) bih, DIB_RGB_COLORS, SRCCOPY) > 0)                     success = TRUE;                  SelectObject(hdcMem, hOldBitmap);                 DeleteDC(hdcMem);             }         }          ReleaseDC(NULL, hdc);     }      if (!success && hBitmap != NULL) {         DeleteObject(hBitmap);         hBitmap = NULL;     }      return hBitmap; } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!