{"id":6931,"date":"2016-08-26T10:12:58","date_gmt":"2016-08-26T08:12:58","guid":{"rendered":"http:\/\/dollarunderscore.azurewebsites.net\/?p=6931"},"modified":"2016-09-06T22:32:59","modified_gmt":"2016-09-06T20:32:59","slug":"having-some-fun-with-images-and-powershell","status":"publish","type":"post","link":"https:\/\/p0wershell.com\/?p=6931","title":{"rendered":"Having some fun with images and PowerShell"},"content":{"rendered":"<p>I&#8217;ve always enjoyed using PowerShell for things outside of the usual &#8220;automating sysadmin tasks&#8221; scope, and some time ago I thought it would be cool to use it to create some &#8220;branded&#8221; wallpapers for my desktop.<\/p>\n<p>Maybe you have a huge number of wallpapers that you have collected over the years, but you&#8217;d like to place the PowerShell logo on them to make them sooo much cooler?<\/p>\n<p>Or maybe you just have a bunch of pictures you&#8217;d like to watermark to show their origin?<\/p>\n<p>Or maybe you just like to know a few things that you can do with the System.Drawing-namespace and PowerShell.<\/p>\n<p>If any of those are true for you, you might want to try out a function I&#8217;ve created called <a href=\"https:\/\/github.com\/AWahlqvist\/MiscUtilities\/blob\/master\/Add-Logo.ps1\" target=\"_blank\">Add-Logo<\/a>! \ud83d\ude42<\/p>\n<p>I mostly created it because it was fun to see if it was possible, and it fulfilled it&#8217;s purpose a long time ago so I never got to iron out all the bugs (which probably are there), but I thought it could be fun to share it anyway.<\/p>\n<p><em>(I should probably add that there are some obvious copyright-related things you need consider before doing this depending on what images you pick and how you want to use the results)<\/em><\/p>\n<p><strong>What does it do then?<\/strong><br \/>\nWell, at first it just placed one picture on another picture. I thought this was pretty neat since I could use Get-ChildItem to pipe picture files to it and place the logo on all of them pretty fast, but there was a problem&#8230;<\/p>\n<p>I soon realized that every background picture was so different that the logo didn&#8217;t look good at the same place on all of them. I started out placing it in the bottom right corner, but some pictures had &#8220;too much going on&#8221; so the logo was hard to notice, or the contrast was to low (especially text based logos). To solve this I added a parameter for &#8220;logo placement&#8221;, so it was possible to pick any of the four corners on the background for the logo. I piped the picture files to the function four times (one for each corner) and got a huge collection of &#8220;branded wallpapers&#8221; where usually at least one out of four looked OK. On top if this, there was an issue with different picture resolutions, on some pictures the logo was huge, and on some it was really tiny.<\/p>\n<p>This was obviously not going to be good enough, so I added some code that would do the following steps:<\/p>\n<li>Sample the pixels of the logo to check what color span it has, the size etc.<\/li>\n<li>Sample the pixels of the background where the logo could be placed<\/li>\n<li>Do some &#8220;analysis&#8221; of this and place the logo as good as possible<\/li>\n<li>Add parameters for controlling the position of the logo, minimum contrast, relative logo size etc. to the function to make it more dynamic<\/li>\n<p>I&#8217;ve had close to zero experience with image processing so this is obviously not anywhere near a professional grade software for doing this kind of thing, but being able to use PowerShell for working with pictures is still pretty cool IMHO \ud83d\ude42<\/p>\n<p>Some usage example follows:<\/p>\n<p>First begin with a picture that can act as a logo, I took the liberty of using the PowerShell logo (registered trademark of Microsoft):<br \/>\n<a href=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/PowerShell-logo.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/PowerShell-logo-300x203.png\" alt=\"PowerShell-logo\" width=\"300\" height=\"203\" class=\"alignnone size-medium wp-image-6971\" srcset=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/PowerShell-logo-300x203.png 300w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/PowerShell-logo.png 550w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>and this picture of a few clouds (should go hand in hand \ud83d\ude42 ):<br \/>\n<a href=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-1024x682.jpg\" alt=\"clouds\" width=\"725\" height=\"483\" class=\"alignnone size-large wp-image-6941\" srcset=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-1024x682.jpg 1024w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-300x200.jpg 300w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-768x512.jpg 768w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-624x416.jpg 624w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds.jpg 1280w\" sizes=\"(max-width: 725px) 100vw, 725px\" \/><\/a><\/p>\n<p>I personally think that logotypes usually look better where the background is &#8220;solid&#8221;, more so than where the contrast is the greatest, so the default settings of the parameters is to have a preference towards that (as long as the minimum allowed contrast level is achieved).<\/p>\n<p>So running the command:<br \/>\n<code><br \/>\nPS> Add-Logo -LogoPictureFile $PoShLogo -BackgroundPictureFile $CloudPicture -DynamicLogoPlacement<br \/>\n<\/code><\/p>\n<p>Will generate the following picture:<br \/>\n<a href=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-PowerShell-logo-TopLeft.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-PowerShell-logo-TopLeft-1024x682.jpg\" alt=\"clouds-PowerShell-logo-TopLeft\" width=\"725\" height=\"483\" class=\"alignnone size-large wp-image-6981\" srcset=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-PowerShell-logo-TopLeft-1024x682.jpg 1024w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-PowerShell-logo-TopLeft-300x200.jpg 300w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-PowerShell-logo-TopLeft-768x512.jpg 768w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-PowerShell-logo-TopLeft-624x416.jpg 624w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/clouds-PowerShell-logo-TopLeft.jpg 1280w\" sizes=\"(max-width: 725px) 100vw, 725px\" \/><\/a><\/p>\n<p>Since the contrast value is met (controlled by the &#8220;MinimumContrast&#8221; parameter) and the color is pretty solid it ended up in the top left corner.<\/p>\n<p>Let&#8217;s do another one, using the same PowerShell logo but on this picture:<br \/>\n<a href=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-1024x679.jpg\" alt=\"CloudFromSpace\" width=\"725\" height=\"481\" class=\"alignnone size-large wp-image-7061\" srcset=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-1024x679.jpg 1024w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-300x199.jpg 300w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-768x510.jpg 768w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-624x414.jpg 624w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace.jpg 1920w\" sizes=\"(max-width: 725px) 100vw, 725px\" \/><\/a><\/p>\n<p>The command is now run with Verbose output which will show you a bit more information about why the function picked a certain corner:<br \/>\n<a href=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose2-1024x146.png\" alt=\"AddLogoVerbose2\" width=\"725\" height=\"103\" class=\"alignnone size-large wp-image-7122\" srcset=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose2-1024x146.png 1024w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose2-300x43.png 300w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose2-768x110.png 768w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose2-624x89.png 624w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose2.png 1570w\" sizes=\"(max-width: 725px) 100vw, 725px\" \/><\/a><\/p>\n<p>Results:<br \/>\n<a href=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-BottomRight.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-BottomRight-1024x679.jpg\" alt=\"CloudFromSpace-PowerShell-logo-BottomRight\" width=\"725\" height=\"481\" class=\"alignnone size-large wp-image-7131\" srcset=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-BottomRight-1024x679.jpg 1024w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-BottomRight-300x199.jpg 300w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-BottomRight-768x510.jpg 768w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-BottomRight-624x414.jpg 624w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-BottomRight.jpg 1920w\" sizes=\"(max-width: 725px) 100vw, 725px\" \/><\/a><\/p>\n<p>This might seem a bit odd at first. The top left corner seems to be a better placement for the logo, and it&#8217;s contrast is certainly greater as you can see from the verbose output, but the problem here is that the logo doesn&#8217;t really fit in the black area and therefore the function sampled some of the &#8220;blue\/earth pixels&#8221; as well since that&#8217;s where parts of the logo would have ended up. <\/p>\n<p>Let&#8217;s try running the same command again, but this time with the &#8220;ProportionFactor&#8221; parameter, which enables scaling of the logotype (higher value makes the logo smaller):<br \/>\n<a href=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose-1024x146.png\" alt=\"AddLogoVerbose\" width=\"725\" height=\"103\" class=\"alignnone size-large wp-image-7111\" srcset=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose-1024x146.png 1024w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose-300x43.png 300w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose-768x110.png 768w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose-624x89.png 624w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/AddLogoVerbose.png 1570w\" sizes=\"(max-width: 725px) 100vw, 725px\" \/><\/a><\/p>\n<p>Results:<br \/>\n<a href=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-TopLeft.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-TopLeft-1024x679.jpg\" alt=\"CloudFromSpace-PowerShell-logo-TopLeft\" width=\"725\" height=\"481\" class=\"alignnone size-large wp-image-7121\" srcset=\"https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-TopLeft-1024x679.jpg 1024w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-TopLeft-300x199.jpg 300w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-TopLeft-768x510.jpg 768w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-TopLeft-624x414.jpg 624w, https:\/\/p0wershell.com\/wp-content\/uploads\/2016\/08\/CloudFromSpace-PowerShell-logo-TopLeft.jpg 1920w\" sizes=\"(max-width: 725px) 100vw, 725px\" \/><\/a><\/p>\n<p>Now the top left corner had both the greatest contrast and the most solid color since the logo actually fits in the black area!<\/p>\n<p>As you can see, the function usually needs some tuning from the standard values depending on the logo you are using (play around with MinimumContrast and MaxColorSpan!), but once you&#8217;re happy with a few test pictures, you can usually just pipe all the images you want to it and you&#8217;ll have a bunch of &#8220;branded&#8221; desktop wallpapers to use!<\/p>\n<p>The function also includes other parameters, for example how close to the edge you want to place the logo or if you just want to place it in the same corner on all of the pictures.<\/p>\n<p><strong>Summary<\/strong><br \/>\nWhile the task of manipulating images can be solved in a lot of other (better\/more efficient) ways, I think it&#8217;s still pretty cool that you can use PowerShell to achieve something like this. So while the code itself in this function isn&#8217;t really something to write home about, the fact that PowerShell can be used for such a variety of tasks kind of is!<\/p>\n<p>So, as I like to say&#8230; Keep automating <em>anything<\/em> \ud83d\ude42<\/p>\n<p><strong><em>Oh, and if you missed the link above, <a href=\"https:\/\/github.com\/AWahlqvist\/MiscUtilities\/blob\/master\/Add-Logo.ps1\" target=\"_blank\">the code can be found here<\/a>.<\/em><\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve always enjoyed using PowerShell for things outside of the usual &#8220;automating sysadmin tasks&#8221; scope, and some time ago I thought it would be cool to use it to create some &#8220;branded&#8221; wallpapers for my desktop. Maybe you have a huge number of wallpapers that you have collected over the years, but you&#8217;d like to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[21],"tags":[1231,301,1241],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3Zj0A-1NN","_links":{"self":[{"href":"https:\/\/p0wershell.com\/index.php?rest_route=\/wp\/v2\/posts\/6931"}],"collection":[{"href":"https:\/\/p0wershell.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/p0wershell.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/p0wershell.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/p0wershell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6931"}],"version-history":[{"count":0,"href":"https:\/\/p0wershell.com\/index.php?rest_route=\/wp\/v2\/posts\/6931\/revisions"}],"wp:attachment":[{"href":"https:\/\/p0wershell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6931"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/p0wershell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6931"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/p0wershell.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6931"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}