Winapi 从加载到内存中的24位BMP文件中获取HBITMAP
我有一个24位BMP文件加载到RAM中,我正在尝试为这个图像文件创建一个HBITMAP。我找到了一些我一直在尝试的例子,但似乎无法奏效。基本上,我需要一个文件的HBITMAP,这样我就可以卸载文件并保留HBITMAP,以后可以用DeleteObject()处理它。由于此位图在我的应用程序中很早就加载了,所以没有应用程序窗口,因此没有HDC。这就是我到目前为止所做的:-Winapi 从加载到内存中的24位BMP文件中获取HBITMAP,winapi,bitmap,Winapi,Bitmap,我有一个24位BMP文件加载到RAM中,我正在尝试为这个图像文件创建一个HBITMAP。我找到了一些我一直在尝试的例子,但似乎无法奏效。基本上,我需要一个文件的HBITMAP,这样我就可以卸载文件并保留HBITMAP,以后可以用DeleteObject()处理它。由于此位图在我的应用程序中很早就加载了,所以没有应用程序窗口,因此没有HDC。这就是我到目前为止所做的:- HBITMAP cBitmap; // This should be where my bitmap handle ends
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);
出于某种让我困惑的原因,cBitmap最终为空。还有一件事让我困惑。。。DIB_RGB_颜色意味着BITMAPINFO有一个指向文字RGB值的指针,但是对于没有调色板的24位图像,它是如何工作的呢?如果您是从磁盘加载文件,那么使用
LR_LOADFROMFILE
标志的LoadImage()
可能是最简单的方法
要从已加载到内存中的文件数据创建HBITMAP
,可以执行以下类似操作:
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;
}
嗯,
GetObject
不是这样工作的。用法是
GetObject(handle, sizeof(object), &object);
在您的情况下,期望是您将其称为
BITMAP bitmap;
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
您没有将指针传递给位图
结构,因此行为未定义
您根本不需要GetObject
。您已经有了HBITMAP
。它位于hBitmap
变量中
cBitmap = hBitmap;
你好谢谢你的回答,但你一定错过了我问题中的一些要点。首先,位图已加载到内存中,无法使用LoadImage/LoadBitmap()加载,因为它是嵌入在二进制数据块中的.bmp文件。我从这个二进制数据块中提取.bmp文件,并需要从中创建一个HBITMAP。其次,正如我所说的,创建HBITMAP是在我的应用程序启动的很早就完成的,所以没有窗口或HDC,所以不能使用GetDC()之类的东西,因为此时没有应用程序窗口。如果
LoadImage()
在您的情况下不起作用,则使用第二种方法。即使没有应用程序窗口,也可以使用GetDC(NULL)
获取屏幕的设备上下文(实际上是桌面窗口)。所以,这对你的案子来说应该很好。