How can I convert a WIC bitmap to a Windows Runtime SoftwareBitmap? part 1: Via an encoded stream

Raymond Chen

Say you have produced a bitmap with the Windows Imaging Component, also known as WIC, and you want to convert it to a Windows Runtime Software­Bitmap, say, because you want to use it as a XAML Software­Bitmap­Source so you can display it in a XAML BitmapImage.

We’ll be trying to solve this problem over the next few days, coming up with simpler and simpler solutions, until we get down to a one-liner. But let’s not get ahead of ourselves.

Well, let’s see. There are only a few Windows Runtime methods that produce a Software­Bitmap. There are some conversion methods on Software­Bitmap itself, but they assume you already have a Software­Bitmap. Fortunately, there’s also Bitmap­Decoder.

So you might come up with this:

namespace winrt
    using namespace winrt::Windows::Foundation;
    using namespace winrt::Windows::Graphics::Imaging;
    using namespace winrt::Windows::Storage::Streams;

    ToSoftwareBitmap(IWICBitmapSource* wicBitmap)
    // Boilerplate code to save the bitmap as a PNG stream
    winrt::com_ptr<::IStream> stream;
        CreateStreamOnHGlobal(nullptr, TRUE, stream.put()));
    auto bitmapEncoder = winrt::create_instance<
        stream.get(), WICBitmapEncoderNoCache));
    winrt::com_ptr<IWICBitmapFrameEncode> frameEncoder;
        frameEncoder.put(), nullptr));
        wicBitmap, nullptr));

    // Rewind the stream so we can load it into a BitmapDecoder
        { 0, 0 }, STREAM_SEEK_SET, nullptr));

    // Convert to a Windows Runtime RandomAccessStream.
    auto randomAccessStream = winrt::capture<
        CreateRandomAccessStreamOverStream, stream.get(),

    // Convert the stream to a SoftwareBitmap.
    auto decoder = co_await winrt::BitmapDecoder::CreateAsync(
    co_return co_await decoder.GetSoftwareBitmapAsync();

This is very straightforward, but quite cumbersome. And you might feel a littly icky that you’re encoding the bitmap as a PNG, only to immediately decode it back into a bitmap. Plus there’s the complication that the Windows Runtime BitmapDecoder decodes asynchronously, so you have to do coroutine stuff to get the answer out.

Fortunately, there’s a better way. We’ll look at it next time.


Discussion is closed.

Feedback usabilla icon