Using RenderTargetBitmap

RenderTargetBitmap is a very useful UWP class if you are looking to render a piece of XAML to an image.

Some use cases that come to mind are saving a signature from an InkCanvas or maybe even more common to generate an image for a live tile.

The visual tree

One of the most important prerequisites is that the control you are trying to render is part of the Visual Tree. That means that you cannot just instantiate a UIElement and pass it in to the RenderTargetBitmap, but rather you need to pick it up directly from the page. That is easy enough when you’re rendering an image when your app is in the foreground but becomes a bit more tricky when you are rendering the image in your background task.

The key in a background task is to use XamlReader.Load() method to load your control, rather than just initializing it.
If your control is complex and cannot be described in a simple XAML string you can use another trick. Use the Reader to load a basic XAML control and add your UIElement as a child there.

1
2
var element = (Border)XamlReader.Load("<Border xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'/>");
element.Child = myUserControl;

Rendered image output

The second important thing to know about RenderTargetBitmap is that it is DPI dependent and maxes out at 4096x4096. That means that the output image size will be scaled according to DPI (i.e. for a DPI of 150%, a 100x100 control will result in a 150x150 image).

This might not always be a big problem, but when you are rendering images for a Live Tile, you need exact sizes. For those times, there are a couple of ways to account for it.
You can find the DPI setting before you render and force a render size to account for that but that might be difficult or impossible in a background task.
The second and easier way is to ensure that we resize the image after we render. If you rendering images for live tiles, you need to resize it anyway to match the tile size requirement.
Furthermore, if you are using the same image for multiple tile sizes (medium, wide), you can use the same technique to resize and crop your image. I’ll share some code for that in another post.

Share Comments