Converting Text to Image

by Feb 18, 2019

WPF (Windows Presentation Foundation)is not just a technique to create UIs. You can create any type of vector-based graphics composition and save it to a graphics file.

Here is a simple example that takes any text and font, and renders it into a PNG file:

function Convert-TextToImage
{
  param
  (
    [String]
    [Parameter(Mandatory)]
    $Text,
    
    [String]
    $Font = 'Consolas',
    
    [ValidateRange(5,400)]
    [Int]
    $FontSize = 24,
    
    [System.Windows.Media.Brush]
    $Foreground = [System.Windows.Media.Brushes]::Black,
    
    [System.Windows.Media.Brush]
    $Background = [System.Windows.Media.Brushes]::White
  )
  
  $filename = "$env:temp\$(Get-Random).png"

  # take a simple XAML template with some text  
  $xaml = @"
<TextBlock
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns_x="http://schemas.microsoft.com/winfx/2006/xaml">$Text</TextBlock>
"@

  Add-Type -AssemblyName PresentationFramework
  
  # turn it into a UIElement
  $reader = [XML.XMLReader]::Create([IO.StringReader]$XAML)
  $result = [Windows.Markup.XAMLReader]::Load($reader)
  
  # refine its properties
  $result.FontFamily = $Font
  $result.FontSize = $FontSize
  $result.Foreground = $Foreground
  $result.Background = $Background
  
  # render it in memory to the desired size
  $result.Measure([System.Windows.Size]::new([Double]::PositiveInfinity, [Double]::PositiveInfinity))
  $result.Arrange([System.Windows.Rect]::new($result.DesiredSize))
  $result.UpdateLayout()
  
  # write it to a bitmap and save it as PNG
  $render = [System.Windows.Media.Imaging.RenderTargetBitmap]::new($result.ActualWidth, $result.ActualHeight, 96, 96, [System.Windows.Media.PixelFormats]::Default)
  $render.Render($result)
  Start-Sleep -Seconds 1
  $encoder = [System.Windows.Media.Imaging.PngBitmapEncoder]::new()
  $encoder.Frames.Add([System.Windows.Media.Imaging.BitmapFrame]::Create($render))
  $filestream = [System.IO.FileStream]::new($filename, [System.IO.FileMode]::Create)
  $encoder.Save($filestream)
  
  # clean up
  $reader.Close() 
  $reader.Dispose()
  
  $filestream.Close()
  $filestream.Dispose()
  
  # return the file name for the generated image
  $filename 
}

Here is how to use:

 
PS> $file = Convert-TextToImage -Text 'Red Alert!' -Font Stencil -FontSize 60 -Foreground Red -Background Gray

PS> Invoke-Item -Path $file
 

Your learning points:

  • With XAML, an XML-based UI description language, you can define graphics
  • PowerShell can use the [Windows.Markup.XAMLReader] class to easily convert any valid XAML into a UIElement object.
  • UIElement objects can be saved as graphics file, for example as a PNG image, can be displayed as a window, or printed. In this example, we focused on saving to file, and we used a very simple XAML definition. Maybe you got curious now. Google for any of the methods used in this example, and you find plenty of reading.

psconf.eu – PowerShell Conference EU 2019 – June 4-7, Hannover Germany – visit www.psconf.eu There aren’t too many trainings around for experienced PowerShell scripters where you really still learn something new. But there’s one place you don’t want to miss: PowerShell Conference EU – with 40 renown international speakers including PowerShell team members and MVPs, plus 350 professional and creative PowerShell scripters. Registration is open at www.psconf.eu, and the full 3-track 4-days agenda becomes available soon. Once a year it’s just a smart move to come together, update know-how, learn about security and mitigations, and bring home fresh ideas and authoritative guidance. We’d sure love to see and hear from you!

Twitter This Tip! ReTweet this Tip!

v