I have an application which loads some blob data out of a database which can represent png formatted or raw binary data for various bitmaps and icons. This is being stored
A slight variation on the answer provided by AJG85, that employs SHCreateMemStream in place of CreateStreamOnHGlobal
. SHCreateMemStream
was introduced as a public API in Windows Vista, and provides the benefit of creating an IStream
over an existing region in memory, thus avoiding an additional memory allocation:
#include
#include
#include
#include
#include
#pragma comment(lib, "Shlwapi.lib")
#if defined(_DEBUG)
# pragma comment(lib, "comsuppwd.lib")
#else
# pragma comment(lib, "comsuppw.lib")
#endif
HBITMAP from_data(std::vector const& data)
{
if (data.empty())
{
_com_issue_error(E_INVALIDARG);
}
auto const stream { ::SHCreateMemStream(&data[0], static_cast(data.size())) };
if (!stream)
{
_com_issue_error(E_OUTOFMEMORY);
}
_COM_SMARTPTR_TYPEDEF(IStream, __uuidof(IStream));
IStreamPtr sp_stream { stream, false };
CImage img {};
_com_util::CheckError(img.Load(sp_stream));
return img.Detach();
}
This implementation either throws a _com_error
, or returns an HBITMAP
that refers to the image constructed from the in-memory data.
When the function returns, the memory buffer can be safely freed. The returned HBITMAP
is owned by the caller, and needs to be released with a call to DeleteObject.