Passing a Win32 HBITMAP to WinRT/UWP SoftwareBitmap
Categories Computer Science, Microsoft, Software, Uncategorized, Windows0 CommentsWith the advent of machine learning and visual recognition it goes without saying that passing graphical information in memory is a more common scenario. This code snippet hopes to help the many queries that try to accomplish it in the Windows ecosystem. Especially going from Win32 to WinRT/UWP world.
PICTDESC pd; // Capture picture info and plug the HBITMAP
LPPICTURE picture; // Holds our picture data
LPSTREAM stream; // Staging bridge buffer to WinRT/UWP
// WinRT Buffer receiving bitmap data.
ComPtr spRandomAccessStream;
We get the bitmap buffer from COM API
bool result = false;
pd.cbSizeofstruct = sizeof(PICTDESC);
pd.picType = PICTYPE_BITMAP;
pd.bmp.hbitmap = hBitmap;
pd.bmp.hpal = NULL;
HRESULT res = OleCreatePictureIndirect(&pd, IID_IPicture, false,
reinterpret_cast<void**>(&picture));
if (!SUCCEEDED(res))
return;
res = CreateStreamOnHGlobal(0, true, &stream);
if (!SUCCEEDED(res))
{
picture->Release();
return;
}
Marshaling bitmap buffer from COM API world to WinRT/UWP space.
CreateRandomAccessStreamOverStream(stream, BSOS_DEFAULT, IID_PPV_ARGS(&spRandomAccessStream));
Once we have the RandomAccessStream populated it’s vanilla WinRT walk in the park:
task< BitmapDecoder^ >
getDecoderTask(BitmapDecoder::CreateAsync((reinterpret_cast(spRandomAccessStream.Get()))));
auto continuation = getDecoderTask.then([](BitmapDecoder ^bitmapDecoder) {
task getSoftwareBitmap(bitmapDecoder->GetSoftwareBitmapAsync());
getSoftwareBitmap.then([](SoftwareBitmap ^softwareBitmap)
{
// softwareBitmap is your bitmap in WinRT/UWP World!
});
});
// Wait for the continuation to finish and handle any
// error that occurs.
try
{
wcout << L"Waiting for tasks to finish..." << endl;
continuation.wait();
// Alternatively, call get() to produce the same result.
//continuation.get();
}
catch (const exception& e)
{
wcout << L"Caught exception." << endl;
}