{"id":1331,"date":"2014-02-25T19:44:23","date_gmt":"2014-02-25T18:44:23","guid":{"rendered":"http:\/\/www.nuonsoft.com\/blog\/?p=1331"},"modified":"2014-03-05T20:57:34","modified_gmt":"2014-03-05T19:57:34","slug":"introduction-to-wic-how-to-use-wic-to-load-an-image-and-draw-it-with-tranparency-using-only-gdi","status":"publish","type":"post","link":"https:\/\/www.nuonsoft.com\/blog\/2014\/02\/25\/introduction-to-wic-how-to-use-wic-to-load-an-image-and-draw-it-with-tranparency-using-only-gdi\/","title":{"rendered":"Introduction to WIC: How to use WIC to load an image, and draw it with tranparency using only GDI?"},"content":{"rendered":"<p>A while ago I wrote an article: <a href=\"http:\/\/www.nuonsoft.com\/blog\/2011\/10\/17\/introduction-to-wic-how-to-use-wic-to-load-an-image-and-draw-it-with-gdi\/\">&#8220;Introduction to WIC: How to use WIC to load an image, and draw it with GDI?&#8221;<\/a><\/p>\n<p>The code in that article didn&#8217;t handle transparency.<br \/>\nIt&#8217;s actually trivial to implement transparency in that sample code.<!--more--><br \/>\nFirst thing you have to do is modify CNuonImg::Open() and specify GUID_WICPixelFormat32bppPBGRA, which is a pre-multiplied alpha format, instead of GUID_WICPixelFormat32bppBGR.<br \/>\nSecond, modify CNuonImg::Render() as follows (changes are highlighted):<\/p>\n<pre class=\"brush: cpp; highlight: [19,27,28,29,47,57,58,59,60,61,62,64,65,72,73]; title: ; notranslate\" title=\"\">void CNuonImg::Render(HDC hDC, UINT x, UINT y, UINT cx, UINT cy)\r\n{\r\n\t\/\/ Make sure an image has been loaded\r\n\tif (!IsLoaded())\r\n\t\tthrow WINCODEC_ERR_WRONGSTATE;\r\n\r\n\t\/\/ Get the WIC factory from the singleton wrapper class\r\n\tIWICImagingFactory* pFactory = CWICImagingFactory::GetInstance().GetFactory();\r\n\tif (!pFactory)\r\n\t\tthrow WINCODEC_ERR_NOTINITIALIZED;\r\n\r\n\t\/\/ Create a WIC image scaler to scale the image to the requested size\r\n\tCComPtr&lt;IWICBitmapScaler&gt; pScaler = nullptr;\r\n\tIfFailedThrowHR(pFactory-&gt;CreateBitmapScaler(&amp;pScaler));\r\n\tIfFailedThrowHR(pScaler-&gt;Initialize(m_pConvertedFrame, cx, cy, WICBitmapInterpolationModeFant));\r\n\r\n\t\/\/ Render the image to a GDI device context\r\n\tHBITMAP hDIBBitmap = NULL;\r\n\tHDC memDC = NULL;\r\n\ttry\r\n\t{\r\n\t\t\/\/ Get a DC for the full screen\r\n\t\tHDC hdcScreen = GetDC(NULL);\r\n\t\tif (!hdcScreen)\r\n\t\t\tthrow 1;\r\n\r\n\t\tHDC memDC = CreateCompatibleDC(hdcScreen);\r\n\t\tif (!memDC)\r\n\t\t\tthrow 2;\r\n\r\n\t\tBITMAPINFO bminfo;\r\n\t\tZeroMemory(&amp;bminfo, sizeof(bminfo));\r\n\t\tbminfo.bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);\r\n\t\tbminfo.bmiHeader.biWidth        = cx;\r\n\t\tbminfo.bmiHeader.biHeight       = -(LONG)cy;\r\n\t\tbminfo.bmiHeader.biPlanes       = 1;\r\n\t\tbminfo.bmiHeader.biBitCount     = 32;\r\n\t\tbminfo.bmiHeader.biCompression  = BI_RGB;\t\t\r\n\r\n\t\tvoid* pvImageBits = nullptr;\t\/\/ Freed with DeleteObject(hDIBBitmap)\r\n\t\thDIBBitmap = CreateDIBSection(hdcScreen, &amp;bminfo, DIB_RGB_COLORS, &amp;pvImageBits, NULL, 0);\r\n\t\tif (!hDIBBitmap)\r\n\t\t\tthrow 3;\r\n\r\n\t\tReleaseDC(NULL, hdcScreen);\r\n\r\n\t\tHBITMAP hOldBitmap = (HBITMAP)::SelectObject(memDC, hDIBBitmap);\r\n\r\n\t\t\/\/ Calculate the number of bytes in 1 scanline\r\n\t\tUINT nStride = DIB_WIDTHBYTES(cx * 32);\r\n\t\t\/\/ Calculate the total size of the image\r\n\t\tUINT nImage = nStride * cy;\r\n\t\t\/\/ Copy the pixels to the DIB section\r\n\t\tIfFailedThrowHR(pScaler-&gt;CopyPixels(nullptr, nStride, nImage, reinterpret_cast&lt;BYTE*&gt;(pvImageBits)));\r\n\r\n\t\t\/\/ Copy the bitmap to the target device context\r\n\t\tBLENDFUNCTION bf;\r\n\t\tbf.AlphaFormat = AC_SRC_ALPHA;\r\n\t\tbf.BlendFlags = 0;\r\n\t\tbf.BlendOp = AC_SRC_OVER;\r\n\t\tbf.SourceConstantAlpha = 255;\r\n\t\t::AlphaBlend(hDC, x, y, cx, cy, memDC, 0, 0, cx, cy, bf);\r\n\r\n\t\t::SelectObject(memDC, hOldBitmap);\r\n\t\tDeleteDC(memDC);\r\n\t\tDeleteObject(hDIBBitmap);\r\n\t}\r\n\tcatch (...)\r\n\t{\r\n\t\tif (hDIBBitmap)\r\n\t\t\tDeleteObject(hDIBBitmap);\r\n\t\tif (memDC)\r\n\t\t\tDeleteDC(memDC);\r\n\t\t\/\/ Rethrow the exception, so the client code can handle it\r\n\t\tthrow;\r\n\t}\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>A while ago I wrote an article: &#8220;Introduction to WIC: How to use WIC to load an image, and draw it with GDI?&#8221; The code in that article didn&#8217;t handle transparency. It&#8217;s actually trivial to implement transparency in that sample code.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,17],"tags":[130,131],"class_list":["post-1331","post","type-post","status-publish","format-standard","hentry","category-c","category-software-development","tag-wic","tag-windows-imaging-component"],"_links":{"self":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts\/1331","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/comments?post=1331"}],"version-history":[{"count":10,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts\/1331\/revisions"}],"predecessor-version":[{"id":1343,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/posts\/1331\/revisions\/1343"}],"wp:attachment":[{"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/media?parent=1331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/categories?post=1331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nuonsoft.com\/blog\/wp-json\/wp\/v2\/tags?post=1331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}