我有一个应用程序,它从数据库中加载一些 blob 数据,这些数据可以表示 png 格式或各种位图和图标的原始二进制数据。这被存储在std::vector<unsigned char>
我在用着CImageList
用于在树视图、工具栏图像等中显示各种图像的对象,但问题是从内存中的数据创建位图会变得模糊,就像在执行如下操作时缺少像素一样:
std::vector<unsigned char> bits;
HBITMAP hbitmap = CreateBitmap(16, 16, 1, 32, bits.data());
为了暂时解决这个问题,我只需将向量中的 data() 写入临时文件,然后使用 LoadImage 将其读回并从中创建 HBITMAP。这工作得很好,但是这无疑是一个无耻的黑客行为,我希望这应该是完全没有必要的。
我在网上查了一下,但没有找到任何关于如何“正确”从内存创建 hbitmap 的真正好的例子。我希望能够创建这些位图并将其添加到图像列表中,而无需任何文件 I/O,并且如果可能的话,也无需复制有限数量的数据。
寻找最好的方法来做到这一点,显然 Windows 特定的代码是可以的。
UPDATE:
根据 jdv 的回答,我开始使用 CreateCompatibleBitmap、CreateDIBitmap,最后是 CreateDIBSection。所有这些最终都创建了可爱的黑色位图,而不是之前的模糊位图,所以我一定又做错了什么,我的猜测是因为这个位图创建是在一个没有屏幕 dc 或窗口概念的对象中完成的GetDC(NULL)
and CreateCompatibleDC(NULL)
都不好。示例代码:
BITMAPINFO bmi;
ZeroMemory(&bmi, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biHeight = 16;
bmi.bmiHeader.biWidth = 16;
bmi.bmiHeader.biPlanes = 1;
HDC dc = CreateCompatibleDC(NULL);
HBITMAP hbitmap = CreateDIBSection(dc, &bmi, DIB_RGB_COLORS, (void**)blobData.GetMember<FILEDATAFIELD_DATA>().data(), NULL, 0);
我现在当然认为必须有一种更简单的方法来解决这个问题,也许可以完全避免 HBITMAP 并直接与CBitmap
班级?当涉及到将图像添加到CImageList
我在用着CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask)
反正。有谁知道初始化一个简单的方法CBitmap
对象从一个std::vector<unsigned char>
?