题
我有一个应用程序,该应用程序从数据库中加载一些BLOB数据,该数据库可以代表各种位图和图标的PNG格式或原始二进制数据。这被存储在一个 std::vector<unsigned char>
我在用着 CImageList
在树视图,工具栏图像等中显示各种图像的对象,但是问题是从内存中的数据创建位图正在浮出水面,就像在做类似以下操作时,它仿佛缺少像素:
std::vector<unsigned char> bits;
HBITMAP hbitmap = CreateBitmap(16, 16, 1, 32, bits.data());
为了解决此问题,我只是简单地将矢量中的数据()写入临时文件,然后使用LoadImage将其重新读取并从中读取HBITMAP。但是,这是一个完美的工作,这是一个无耻的黑客,我希望完全不必要。
我在网上环顾四周,但还没有找到任何非常好的示例,说明如何从内存中“正确”创建HBITMAP。我希望能够创建这些位图以添加到图像列表中,而无需任何文件I/O,并且在可能的情况下将数据复制的数量有限。
寻找这样做的最佳方法,显然特定于Windows代码是可以的。
更新:
根据JDV的答案,我开始使用CreateCompatibleBitMap,CreateSibitMap,最后是CreateIbsection。所有这些最终都创建了可爱的黑色位图,而不是以前的模糊位图,因此我必须再次做错事,我的猜测是因为这个位图创建是在没有屏幕dc或窗口的对象中完成的, GetDC(NULL)
和 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);
我现在当然认为,可能必须有一种更简单的方法来解决这个问题 CBitmap
班级?当涉及到将图像添加到 CImageList
我在用着 CBitmap::FromHandle(HBITMAP hbitmap, COLORREF mask)
反正。有人知道初始化一个简单的方法吗 CBitmap
来自a的对象 std::vector<unsigned char>
?
解决方案 2
使用gdiplus,我得到的东西很好,并且不涉及拉任何牙齿!
Gdiplus::Bitmap* pBitmap = NULL;
IStream* pStream = NULL;
HRESULT hResult = ::CreateStreamOnHGlobal( NULL, TRUE, &pStream );
if(hResult == S_OK && pStream)
{
hResult = pStream->Write(&bits[0], ULONG(bits.size()), NULL);
if(hResult == S_OK)
pBitmap = Gdiplus::Bitmap::FromStream(pStream);
pStream->Release();
}
编辑: 每个Jegatheesh都改变了
其他提示
我会用 CreateCompatibleBitmap
, ,然后致电 SetDIBits
用数据填充它。这些是我看到的功能,尽管冗长,但setDibits非常灵活。
在我的MFC年中, CreateBitmap
由于怀疑性能问题而避免了。