How can I convert a WIC bitmap to a Windows Runtime SoftwareBitmap? part 4: Handing it over

Raymond Chen

Last time, we converted a WIC bitmap to a Windows Runtime SoftwareBitmap by copying the pixels of the WIC bitmap directly into the SoftwareBitmap. But you don’t even have to copy pixels at all!

The ISoftware­Bitmap­Native­Factory::Create­From­WIC­Bitmap method gives you a direct transfer of a IWICBitmap into a SoftwareBitmap.

#include <windows.graphics.imaging.interop.h>

winrt::SoftwareBitmap ToSoftwareBitmap(IWICBitmap* wicBitmap)
{
    winrt::SoftwareBitmap bitmap{ nullptr };

    auto native = winrt::create_instance<
        ISoftwareBitmapNativeFactory>(
        CLSID_SoftwareBitmapNativeFactory);

    winrt::check_hresult(native->CreateFromWICBitmap(
        wicBitmap, true, winrt::guid_of<winrt::SoftwareBitmap>(),
        winrt::put_abi(bitmap)));

    return bitmap;
}

First, we create a null Software­Bitmap that will hold the result.

Next, we ask for the ISoftware­Bitmap­Native­Factory interface from a Software­Bitmap­Native­Factory.

Finally, we call the Create­From­WIC­Bitmap method to transmogrify the wicBitmap into a Software­Bitmap, saying that the resulting bitmap is read-only (true).

And then we return the resulting bitmap.

The Software­Bitmap doesn’t make a copy of the IWICBitmap. It just copies the reference. As a result, no pixels are copied at all!

Since the Software­Bitmap has a reference to the original IWICBitmap, you have two usage patterns.

If you are “giving away” the IWICBitmap, then you can pass forceReadOnly = false to make the resulting Software­Bitmap read-write. The Software­Bitmap now owns the IWICBitmap and may choose to modify it.

If you are sharing the IWICBitmap, then pass forceReadOnly = true to make the resulting Software­Bitmap read-only. That way, the Software­Bitmap won’t make changes to the IWICBitmap.

If your IWICBitmap is a no-cache bitmap created from a IWICBitmapSource, then you need to pass forceReadOnly = true because the pixels are being generated on the fly and there is no buffer to modify.

I wrote out the above sequence in multiple steps, but you can collapse it into a one-liner:

winrt::SoftwareBitmap ToSoftwareBitmap(IWICBitmap* wicBitmap)
{
    return winrt::capture(
        winrt::create_instance
            <ISoftwareBitmapNativeFactory>
            (CLSID_SoftwareBitmapNativeFactory),
        &ISoftwareBitmapNativeFactory::CreateFromWICBitmap,
        wicBitmap, false);
}

Note that this call will fail if the IWICBitmap is in a format not supported by Software­Bitmap.

Bonus chatter: A Software­Bitmap can have an IWICBitmap inside it, or it can have a IMF2DBuffer inside (for video formats like NV12). If you have a Software­Bitmap, you can reach inside and access the inner bitmap buffer by using ISoftware­Bitmap­Native::Get­Data.

4 comments

Discussion is closed. Login to edit/delete existing comments.

  • 紅樓鍮 0

    This looks like something that can easily be googled. Indeed, the Microsoft Docs page of CreateFromWICBitmap shows up as the literal first result when googling the keywords windows.graphics.imaging.softwarebitmap iwicbitmap. I guess the mini-series is intended to showcase the multiple ways you can create a SoftwareBitmap, but it still feels a bit silly.

    • Richard Russell 0

      Yeah, I reckon Raymond is running out of material. Telling us three ways not to do something, before telling us the obviously best way, fills a lot more pages.

      • Me Gusta 0

        Or there is a much simpler and logical explanation.
        For example, suppose you don’t get the bitmap through WIC, how would you load it? This series showed the other ways of loading information into a bitmap.

    • Raymond ChenMicrosoft employee 1

      The documentation somewhat misleadingly says “Creates an *ISoftwareBitmapNative* from the provided IWICBitmap.” So you’ll read the description and say, “That’s not what I want. I want a SoftwareBitmap, not an ISoftwareBitmapNative.” Believe it or not, this sequence was based on an actual customer asking how to create a SoftwareBitmap and trying out all sorts of things without ever considering CreateFromWICBitmap. Sorry you didn’t enjoy the trip.

Feedback usabilla icon