How to render an SVG file in XAML on Windows 10 UWP

How to render an SVG file in XAML on Windows 10 UWP

GitHub timeline can be pretty useful if you follow the right people. :) Lately I've discovered a couple of great open source projects this way, and one of them is SvgForXaml. It's using Win2D to draw SVG files straight into XAML!

There are a couple of easy steps to take in order to get this library up and running. As far as I can see, there's no Nuget package at the moment, so one way to add the library to your project is to make a build yourself and add it to references. I had some build problems out of the box with the solution that's downloadable from GitHub, so I just added the necessary projects to my demo solution, but you could just as easily create a new project with all the files and build it that way. It relies on Win2D, so don't forget to add the dependency!

The author has just published a Nuget package! :)

Install-Package Mntone.SvgForXaml

I created a blank Universal app and added the Win2D UWP Nuget package and the SvgForXaml reference. Next I took a sample SVG for demo purposes from Wikipedia. The SVG shows the world map. Link to source is here. I called it world.svg and just added to project files.

Win2D UWP Nuget dependency

The only thing I added in XAML was an SvgImage control from Mntone.SvgForXaml.UI.Xaml namespace.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">  
    <svg:SvgImage x:Name="SvgControl"/>
</Grid>  

Then in code behind, I subscribed to page Loaded event and loaded the SVG from a file by calling the SvgControl.LoadFileAsync(file); method.

public MainPage()  
{
    this.InitializeComponent();

    this.Loaded += MainPage_Loaded;
}

private async void MainPage_Loaded(object sender, RoutedEventArgs e)  
{
    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///world.svg"));

    await this.SvgControl.LoadFileAsync(file);
}

It is literally that simple!

You can also cleanup the resources when navigating from the page

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)  
{
    this.SvgControl.SafeUnload();
}

World map SVG rendered in XAML

One thing to be careful about when working with large images is memory. Use the VS2015 profiler while debugging to learn about any peaks in memory usage so you can handle them better in the early phase of development.

Render to raster image

It's also quite easy to render that SVG to a raster image. Just get the file (for example, created with a FileSavePicker or created in local app folder), get the SVG document and render it to one of the supported types (SvgImageRendererFileFormat enum - Bitmap, Gif, Jpeg, JpegXr, Png, Tiff)

StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("test.jpg", CreationCollisionOption.OpenIfExists);

var content = this.SvgControl.Content;

await SvgImageRenderer.RendererImageAsync(file, new SvgImageRendererSettings()  
{
    Document = content,
    Format = SvgImageRendererFileFormat.Jpeg,
    Scaling = 0.1f,
    Quality = 0.95f
});

And that's it!

RendererImageAsync can sometimes throw an ArgumentException (actually, it's the underlying Win2D CanvasRenderTarget constructor that throws it), so it's a good idea to handle that, too!

Conclusion

This library works with Windows Phone 8.1, Windows 8.1 and Windows 10 UWP. It's really easy to use and I am happy to see SVG support in XAML. Try it out, star it on GitHub, report any issues you find - the source code is available on GitHub along with all the other examples. UWP community rocks!

Happy holidays everyone!

Igor Ralic

igor ralic

View Comments
Microsoft Certified Solutions Developer: Windows Store Apps in C#