{"id":29013,"date":"2006-11-14T10:00:01","date_gmt":"2006-11-14T10:00:01","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2006\/11\/14\/blitting-between-color-and-monochrome-dcs\/"},"modified":"2006-11-14T10:00:01","modified_gmt":"2006-11-14T10:00:01","slug":"blitting-between-color-and-monochrome-dcs","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20061114-01\/?p=29013","title":{"rendered":"Blitting between color and monochrome DCs"},"content":{"rendered":"<p>\nWhen blitting between color and monochrome DCs,\nThe text foreground and background colors play a role.\nWe saw earlier that\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/08\/02\/446605.aspx\">\nwhen blitting from a monochrome DC to a color DC,\nthe color black in the source turns into the destination&#8217;s text color,\nand the color white in the source turns into the destination&#8217;s background\ncolor<\/a>.\nThis came in handy when we wanted to colorize a monochrome bitmap.\n<\/p>\n<p>\nThis trick works in reverse, too.\nIf you blit from a color DC to a monochrome DC,\nthen all pixels in the source that are equal to the background color\nwill turn white, and all other pixels will turn black.\nIn other words, GDI considers a monochrome bitmap to be\n<a HREF=\"http:\/\/www.sciencebob.com\/lab\/q-zebrastripes.html\">\nblack pixels on a white background<\/a>.\n<\/p>\n<p>\nThis trick comes in handy when you want to convert a bitmap with\ncolor-keyed transparency into a color bitmap and a mask.\nSelect the color bitmap into the DC <code>hdcColor<\/code>,\nand create a monochrome bitmap with the same dimensions and select\nit into the DC <code>hdcMask<\/code>.\nThen the following operations will construct the mask:\n<\/p>\n<pre>\n\/\/ let's say that the upper left pixel is the transparent color\nCOLORREF clrTransparent = GetPixel(hdcColor, 0, 0);\nCOLORREF clrBkPrev = SetBkColor(hdcColor, clrTransparent);\nBitBlt(hdcMono, 0, 0, cx, cy, hdcColor, 0, 0, SRCCOPY);\nSetBkColor(hdcColor, clrBkPrev);\n<\/pre>\n<p>\nWe can see this in action in our\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2003\/07\/23\/54576.aspx\">\nscratch program<\/a>\nby making the following changes:\n<\/p>\n<pre>\nvoid\nPaintContent(HWND hwnd, PAINTSTRUCT *pps)\n{\n  <font COLOR=\"blue\">\n  HBITMAP hbmMono = CreateBitmap(100, 100, 1, 1, NULL);\n  HDC hdcMono = CreateCompatibleDC(pps-&gt;hdc);\n  HBITMAP hbmPrev = SelectBitmap(hdcMono, hbmMono);\n  HDC hdcScreen = GetDC(NULL);\n  SetBkColor(hdcScreen, GetSysColor(COLOR_DESKTOP));\n  BitBlt(hdcMono, 0, 0, 100, 100, hdcScreen, 0, 0, SRCCOPY);\n  SetTextColor(pps-&gt;hdc, RGB(0xFF,0,0));\n  SetBkColor(pps-&gt;hdc, RGB(0,0x80,0));\n  BitBlt(pps-&gt;hdc, 0, 0, 100, 100, hdcMono, 0, 0, SRCCOPY);\n  ReleaseDC(NULL, hdcScreen);\n  SelectBitmap(hdcMono, hbmPrev);\n  DeleteDC(hdcMono);\n  DeleteObject(hbmMono);<\/font>\n}\n<\/pre>\n<p>\nWe start by creating a 100&nbsp;&times;&nbsp;100 monochrome bitmap\nand selecting it into a memory DC. This will become our mask.\nNext, we take a screen DC and set its background color to the\ndesktop color and blit from the screen to the monochrome bitmap.\nThis creates a bitmap which is white where the screen has the desktop\ncolor and black where the screen has some other color.\nWe show off we show off this new bitmap by painting it into our\nclient area, but just for fun, I made the foreground pixels\n(black pixels in the monochrome bitmap)\nbright red and the background pixels\n(white pixels in the monochrome bitmap)\ndark green.\n<\/p>\n<p>\nMinimize your windows so the upper left corner of the desktop is\nvisible, and turn off your wallpaper (so the desktop color actually\nmeans something).\nRun this program and observe a copy of your desktop drawn in the\nwindow&#8217;s client area,\nbut with your desktop color turned to green and all the other pixels\nturned to red.\n<\/p>\n<p>\nThe rest of the job of drawing a color bitmap with transparency\nis now comparatively straightforward.\nI&#8217;ll leave it as an exercise.\nHint:\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/08\/03\/447131.aspx\">\nRaster operation 0x00220326 (DSna)\nwill probably be handy<\/a>.\n<\/p>\n<p>\nNext time, we&#8217;ll look at DIB sections as a way of doing\nfast color manipulation, thereby avoiding the need to\nperform the DSna ROP entirely.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When blitting between color and monochrome DCs, The text foreground and background colors play a role. We saw earlier that when blitting from a monochrome DC to a color DC, the color black in the source turns into the destination&#8217;s text color, and the color white in the source turns into the destination&#8217;s background color. [&hellip;]<\/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-29013","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>When blitting between color and monochrome DCs, The text foreground and background colors play a role. We saw earlier that when blitting from a monochrome DC to a color DC, the color black in the source turns into the destination&#8217;s text color, and the color white in the source turns into the destination&#8217;s background color. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/29013","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=29013"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/29013\/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=29013"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=29013"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=29013"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}