{"id":2553,"date":"2008-06-09T16:21:00","date_gmt":"2008-06-09T16:21:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/pfxteam\/2008\/06\/09\/image-colorizer-sample-in-the-june-2008-ctp\/"},"modified":"2008-06-09T16:21:00","modified_gmt":"2008-06-09T16:21:00","slug":"image-colorizer-sample-in-the-june-2008-ctp","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/image-colorizer-sample-in-the-june-2008-ctp\/","title":{"rendered":"Image Colorizer Sample in the June 2008 CTP"},"content":{"rendered":"<p><P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">Continuing the tour of the samples included in the Parallel Extensions June 2008 CTP, we now turn our attention to the &#8220;Image Colorizer&#8221; application.<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">This sample uses the following constructs from Parallel Extensions:<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><SPAN class=\"Inline-codeChar\"><SPAN><FONT face=\"Courier New\">System.Threading.Parallel.For()<\/FONT><\/SPAN><\/SPAN><FONT size=\"3\"><FONT face=\"Calibri\"> <\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><SPAN><FONT size=\"3\"><FONT face=\"Calibri\">and also the following from the standard .NET libraries:<\/FONT><\/FONT><\/SPAN><\/P>\n<P class=\"Inline-code\"><SPAN><FONT face=\"Courier New\">System.ComponentModel.BackgroundWorker<\/FONT><\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN class=\"Inline-codeChar\"><SPAN><FONT face=\"Courier New\">System.Threading.Interlocked.Add()<\/FONT><\/SPAN><\/SPAN><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">The Image Colorizer was originally written by Stephen Toub to demonstrate Tablet PC APIs functionality (see <\/FONT><A href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/bb332387.aspx\"><FONT face=\"Calibri\" size=\"3\">https:\/\/msdn.microsoft.com\/en-us\/library\/bb332387.aspx<\/FONT><\/A><FONT face=\"Calibri\" size=\"3\">) and requires the Microsoft.Ink.DLL to compile.<SPAN>&nbsp; <\/SPAN>If you cannot compile this sample, please obtain the DLL via the <\/FONT><A href=\"https:\/\/www.microsoft.com\/downloads\/details.aspx?FamilyId=B46D4B83-A821-40BC-AA85-C9EE3D6E9699&amp;displaylang=en\"><FONT face=\"Calibri\" size=\"3\">Microsoft XP Tablet SDK<\/FONT><\/A><FONT size=\"3\"><FONT face=\"Calibri\">.<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">The application demonstrates how to recolor an image to preserve either one or more master colors, and optionally to limit such preservation to specific regions selected via ink.<SPAN>&nbsp; <\/SPAN>For this discussion, we will only consider the simple behavior, for which the basic flow is:<\/FONT><\/FONT><\/P>\n<P class=\"MsoListParagraphCxSpFirst\"><SPAN><SPAN><FONT face=\"Calibri\" size=\"3\">1.<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT size=\"3\"><FONT face=\"Calibri\">The user selects a master color by clicking on an image pixel (or multiple colors if the Shift-key is held down while clicking)<\/FONT><\/FONT><\/P>\n<P class=\"MsoListParagraphCxSpMiddle\"><SPAN><SPAN><FONT face=\"Calibri\" size=\"3\">2.<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT size=\"3\"><FONT face=\"Calibri\">The application copies the image bitmap, and kicks off a worker to colorize the image.<SPAN>&nbsp; <\/SPAN>The colorization involves altering each image pixel color towards grayscale depending on its &#8216;closeness&#8217; to the master color(s).<\/FONT><\/FONT><\/P>\n<P class=\"MsoListParagraphCxSpLast\"><SPAN><SPAN><FONT face=\"Calibri\" size=\"3\">3.<\/FONT><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><\/SPAN><\/SPAN><FONT size=\"3\"><FONT face=\"Calibri\">When the new image bitmap has been created, it is drawn to the screen.<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">For example, on the standard Windows Vista image &#8220;Frangipani Flowers&#8221;, we can see the effect of choosing a to colorize on the red of the unopened flower:<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\"><IMG title=\"Original image\" height=\"156\" alt=\"Original image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/21\/2019\/02\/clip_image001_2.jpg\" width=\"244\"><\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">Original image<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\"><\/FONT>&nbsp;<\/P>\n<P class=\"MsoNormal\"><IMG title=\"Colorized image\" height=\"156\" alt=\"Colorized image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/21\/2019\/02\/clip_image002_2.jpg\" width=\"244\"><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">Colorized using red as the master color<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\" align=\"center\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">In particular, this sample application provides a good example of a GUI that performs significant computation whilst providing progress updates.<SPAN>&nbsp; <\/SPAN>Even before we consider parallelizing the work, the application already involves multi-threaded code to ensure that the foreground GUI thread never blocks and remains responsive whilst the computation is occurring.<SPAN>&nbsp; <\/SPAN>The standard mechanism to achieve this is to use a <\/FONT><SPAN class=\"Inline-codeChar\"><SPAN><FONT face=\"Courier New\">System.Component.BackgroundWorker<\/FONT><\/SPAN><\/SPAN><FONT size=\"3\"><FONT face=\"Calibri\"> for performing the expensive computation.<SPAN>&nbsp; <\/SPAN><SPAN>&nbsp;<\/SPAN>It is a good strategy to build your applications in two phases like this: <\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">Phase 1: GUI + BackgroundWorker<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\">Phase 2: GUI + BackgroundWorker with parallelized computation<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Once the basic application is in place with a background worker performing sequential computation, it is relatively straight-forward to extend it to use parallelism. Note: Parallel computation is turned on in the application via the &#8216;check-mark&#8217; button \u2013 you may also wish to add a <\/FONT><SPAN class=\"Inline-codeChar\"><SPAN><FONT face=\"Courier New\">Stopwatch<\/FONT><\/SPAN><\/SPAN><FONT size=\"3\"><FONT face=\"Calibri\"> around the final if-block in Colorize() to validate the speedup if the progress bar is not sufficient for observing the timing.<\/FONT><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT size=\"3\"><FONT face=\"Calibri\"><SPAN>&nbsp;<\/SPAN>The first issue to address when moving to a parallel version of <\/FONT><\/FONT><SPAN class=\"Inline-codeChar\"><SPAN><FONT face=\"Courier New\">Colorize()<\/FONT><\/SPAN><\/SPAN><FONT face=\"Calibri\" size=\"3\"> is achieving multi-threaded access to a <\/FONT><SPAN class=\"Inline-codeChar\"><SPAN><FONT face=\"Courier New\">System.Drawing.Bitmap<\/FONT><\/SPAN><\/SPAN><FONT face=\"Calibri\" size=\"3\">.<SPAN>&nbsp; <\/SPAN>This is conveniently handled already via the <\/FONT><SPAN class=\"Inline-codeChar\"><SPAN><FONT face=\"Courier New\">FastBitmap<\/FONT><\/SPAN><\/SPAN><FONT face=\"Calibri\" size=\"3\"> class which locks the bitmap and provides access to a regular array during manipulation; please see the code for the details.<SPAN>&nbsp; <\/SPAN>The only other change is to ensure that the progress counter manipulation is thread-safe which is achieved by using <\/FONT><SPAN class=\"Inline-codeChar\"><SPAN><FONT face=\"Courier New\">Interlocked.Add(ref pixelsProcessed, width)<\/FONT><\/SPAN><\/SPAN><FONT face=\"Calibri\" size=\"3\"> rather than the non-thread-safe alternative: <\/FONT><FONT face=\"Courier New\"><SPAN class=\"Inline-codeChar\"><SPAN>pixelsProcessed += width.<\/SPAN><\/SPAN><\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Calibri\" size=\"3\">Because the workload is easily parallelizable and there is significant computation performed in each iteration, the <\/FONT><SPAN class=\"Inline-codeChar\"><SPAN><FONT face=\"Courier New\">Colorize()<\/FONT><\/SPAN><\/SPAN><FONT size=\"3\"><FONT face=\"Calibri\"> function achieves essentially a linear speedup, eg 4x on a 4-core machine.<SPAN>&nbsp; <\/SPAN><\/FONT><\/FONT><\/P>\n<P>&nbsp;<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Continuing the tour of the samples included in the Parallel Extensions June 2008 CTP, we now turn our attention to the &#8220;Image Colorizer&#8221; application. &nbsp; This sample uses the following constructs from Parallel Extensions: System.Threading.Parallel.For() and also the following from the standard .NET libraries: System.ComponentModel.BackgroundWorker System.Threading.Interlocked.Add() &nbsp; The Image Colorizer was originally written by Stephen [&hellip;]<\/p>\n","protected":false},"author":482,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[7908],"tags":[7911,7909,7912],"class_list":["post-2553","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pfxteam","tag-code-samples","tag-parallel-extensions","tag-task-parallel-library"],"acf":[],"blog_post_summary":"<p>Continuing the tour of the samples included in the Parallel Extensions June 2008 CTP, we now turn our attention to the &#8220;Image Colorizer&#8221; application. &nbsp; This sample uses the following constructs from Parallel Extensions: System.Threading.Parallel.For() and also the following from the standard .NET libraries: System.ComponentModel.BackgroundWorker System.Threading.Interlocked.Add() &nbsp; The Image Colorizer was originally written by Stephen [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/2553","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/482"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=2553"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/2553\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=2553"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=2553"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=2553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}