我有一个应用程序,该应用程序从数据库中加载一些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 由于怀疑性能问题而避免了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top