Use base64 for Images in WPF-based PowerShell Forms
I'm currently building a notification module to let me know when VMware vCenter alerts go off in my home lab. I plan to share it, and wanted to use a non-standard icon, but didn't want to require a separate download. I knew base64 would be the answer, and ultimately, some C# code from StackExchange helped me figure out what needed to be done.
Here's what it looks like in my application. Note the image being used in both the popup and the notifyicon itself:
Below is the simplified code I used to display the icon within my application popup. The code contains comments that explains each step. It's pretty straightforward: a quick conversion, then setting the image source to the converted stream.
# Add required assembly Add-Type -AssemblyName PresentationFramework
Setup the XAML
[xml]$script:xaml = '
Create the form and set variables
$script:form = [Windows.Markup.XamlReader]::Load((New-Object System.Xml.XmlNodeReader $xaml)) $xaml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $form.FindName($_.Name) -Scope Script }
here's the base64 string
$base64 = "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7 DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAJESURBVHhe7ZZRaiNRDAR9ON//St4JKIskikc3gwaBU1 A/DQ9V/DHk9fl87rgFapPE0XAL1CaJo+EWqE0SR8MtUJskjoZboDZJHA0L7/f79YRxLtO7ZHE0LFDshHEu07tkcTQsUOyEcS7Tu2RxN CxQ7IRxLtO7ZHE03AK1SeJouAVqk8TRcAvUJomj4RaoTRJHwwJ9sCaMc5neJYujYYFiJ4xzmd4li6NhgWInjHOZ3iWLo2GBYieMc5ne JYuj4RaoTRJHwy1QmySOhlugNkkcDbdAbZI4GhbogzVhnMv0LlkcDQsUO2Gcy/QuWRwNCxQ7YZzL9C5ZHA0LFDthnMv0LlkcDbdAbZI 4Gm6B2iRxNNwCtUniaLgFapPE0bBAH6wJ41ymd8niaFig2AnjXKZ3yeJoWKDYCeNcpnfJ4mhYoNgJ41ymd8niaLgFapPE0XAL1CaJo+ EWqE0SR8MtUJskjoYF+mBNGOcyvUsWR8MCxU4Y5zK9SxZHwwLFThjnMr1LFkfDAsVOGOcyvUsWR8MtUJskjoZboDZJHA23QG2SOBpug dokcTTcArVJ4mi4BWqTxNFwC9QmiaPhFqhNEkfDLVCbJI6GW6A2SRwd6V/VJ6UmRxwdKepJqckRR0eKOnm9OUJvTl5PbomjI0WdvN4c oTcnrye3xNGRok5eb47Qm5PXk1vi6EhRJ683R+jNyevJLXF0pKiT15sj9Obk9eSWODpS1JNSkyOOjhT1pNTk2Idv4f/f/I1//C9/P8C PX/4DfF7/AHQpDe71ItxOAAAAAElFTkSuQmCC"
Create a streaming image by streaming the base64 string to a bitmap streamsource
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage $bitmap.BeginInit() $bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($base64) $bitmap.EndInit()
Freeze() prevents memory leaks.
$bitmap.Freeze()
Set source here. Take note in the XAML as to where the variable name was taken.
$thisistheimage.source = $bitmap
Show form
$form.ShowDialog() | Out-Null
Working with PowerShell and WPF makes me realize that *this* is what I always wanted coding to be. Simplified yet powerful!