{"id":108051,"date":"2023-04-14T07:00:00","date_gmt":"2023-04-14T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=108051"},"modified":"2023-04-13T17:43:23","modified_gmt":"2023-04-14T00:43:23","slug":"20230414-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20230414-00\/?p=108051","title":{"rendered":"How can I convert a WIC bitmap to a Windows Runtime SoftwareBitmap? part 4: Handing it over"},"content":{"rendered":"<p>Last time, we converted a WIC bitmap to a Windows Runtime SoftwareBitmap by <a title=\"How can I convert a WIC bitmap to a Windows Runtime SoftwareBitmap? part 3: Filling the SoftwareBitmap directly\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20230413-00\/?p=108048\"> copying the pixels of the WIC bitmap directly into the SoftwareBitmap<\/a>. But you don&#8217;t even have to copy pixels at all!<\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/api\/windows.graphics.imaging.interop\/nf-windows-graphics-imaging-interop-isoftwarebitmapnativefactory-createfromwicbitmap\"> The <code>ISoftware\u00adBitmap\u00adNative\u00adFactory::<wbr \/>Create\u00adFrom\u00adWIC\u00adBitmap<\/code> method<\/a> gives you a direct transfer of a <code>IWICBitmap<\/code> into a <code>SoftwareBitmap<\/code>.<\/p>\n<pre>#include &lt;windows.graphics.imaging.interop.h&gt;\r\n\r\nwinrt::SoftwareBitmap ToSoftwareBitmap(IWICBitmap* wicBitmap)\r\n{\r\n    winrt::SoftwareBitmap bitmap{ nullptr };\r\n\r\n    auto native = winrt::create_instance&lt;\r\n        ISoftwareBitmapNativeFactory&gt;(\r\n        CLSID_SoftwareBitmapNativeFactory);\r\n\r\n    winrt::check_hresult(native-&gt;CreateFromWICBitmap(\r\n        wicBitmap, true, winrt::guid_of&lt;winrt::SoftwareBitmap&gt;(),\r\n        winrt::put_abi(bitmap)));\r\n\r\n    return bitmap;\r\n}\r\n<\/pre>\n<p>First, we create a null <code>Software\u00adBitmap<\/code> that will hold the result.<\/p>\n<p>Next, we ask for the <code>ISoftware\u00adBitmap\u00adNative\u00adFactory<\/code> interface from a <code>Software\u00adBitmap\u00adNative\u00adFactory<\/code>.<\/p>\n<p>Finally, we call the <code>Create\u00adFrom\u00adWIC\u00adBitmap<\/code> method to transmogrify the <code>wicBitmap<\/code> into a <code>Software\u00adBitmap<\/code>, saying that the resulting bitmap is read-only (<code>true<\/code>).<\/p>\n<p>And then we return the resulting bitmap.<\/p>\n<p>The <code>Software\u00adBitmap<\/code> doesn&#8217;t make a copy of the <code>IWICBitmap<\/code>. It just copies the reference. As a result, no pixels are copied at all!<\/p>\n<p>Since the <code>Software\u00adBitmap<\/code> has a reference to the original <code>IWICBitmap<\/code>, you have two usage patterns.<\/p>\n<p>If you are &#8220;giving away&#8221; the <code>IWICBitmap<\/code>, then you can pass <code>forceReadOnly = false<\/code> to make the resulting <code>Software\u00adBitmap<\/code> read-write. The <code>Software\u00adBitmap<\/code> now owns the <code>IWICBitmap<\/code> and may choose to modify it.<\/p>\n<p>If you are sharing the <code>IWICBitmap<\/code>, then pass <code>forceReadOnly = true<\/code> to make the resulting <code>Software\u00adBitmap<\/code> read-only. That way, the <code>Software\u00adBitmap<\/code> won&#8217;t make changes to the <code>IWICBitmap<\/code>.<\/p>\n<p>If your <code>IWICBitmap<\/code> is a no-cache bitmap created from a <code>IWICBitmapSource<\/code>, then you need to pass <code>forceReadOnly = true<\/code> because the pixels are being generated on the fly and there is no buffer to modify.<\/p>\n<p>I wrote out the above sequence in multiple steps, but you can collapse it into a one-liner:<\/p>\n<pre>winrt::SoftwareBitmap ToSoftwareBitmap(IWICBitmap* wicBitmap)\r\n{\r\n    return winrt::capture(\r\n        winrt::create_instance\r\n            &lt;ISoftwareBitmapNativeFactory&gt;\r\n            (CLSID_SoftwareBitmapNativeFactory),\r\n        &amp;ISoftwareBitmapNativeFactory::CreateFromWICBitmap,\r\n        wicBitmap, false);\r\n}\r\n<\/pre>\n<p>Note that this call will fail if the <code>IWICBitmap<\/code> is in a format not supported by <code>Software\u00adBitmap<\/code>.<\/p>\n<p><b>Bonus chatter<\/b>: A <code>Software\u00adBitmap<\/code> can have an <code>IWICBitmap<\/code> inside it, or it can have a <code>IMF2DBuffer<\/code> inside (for video formats like NV12). If you have a <code>Software\u00adBitmap<\/code>, you can reach inside and access the inner bitmap buffer by using <code>ISoftware\u00adBitmap\u00adNative::<wbr \/>Get\u00adData<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just take the whole thing.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-108051","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Just take the whole thing.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/108051","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=108051"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/108051\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=108051"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=108051"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=108051"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}