Save XAML as PNG in a Windows Store App

Do you want to create thumbnails, attachments or other bitmappy representations of your XAML? Very good. After reading this tutorial, you will know how to save any XAML-thingy as a PNG and save it to ApplicationData.Current.LocalFolder. As a bonus, you will learn how to avoid the infamous UnauthorizedAccessException, caused by the image being used by the control.

Grab the demo code here

save as png

Step 1: Save XAML as PNG

To save XAML as a PNG, use the following method:

private async Task SaveImage() {
    var renderTargetBitmap = new RenderTargetBitmap();
    await renderTargetBitmap.RenderAsync(text);
    var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();

    var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("text.png", CreationCollisionOption.ReplaceExisting);

    using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite)) {
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
        encoder.SetPixelData(
            BitmapPixelFormat.Bgra8,
            BitmapAlphaMode.Straight,
            (uint)renderTargetBitmap.PixelWidth,
            (uint)renderTargetBitmap.PixelHeight, 96d, 96d,
            pixelBuffer.ToArray());

        await encoder.FlushAsync();
    }

    await LoadImage();
}

The XAML (the text variable is a TextBox) is now saved to the LocalFolder. If you want to check this, go to c:\users\loek\appdata\local\packages and search for text.png. A folder with a GUID-like name will pop up and there you will find the image.

Step2: Showing the image

To show the image in an Image control, you could just point the ImageSource attribute to ms-appdata:///local/text.png but a funny thing will happen the second time you try to write to the file. You will get an UnauthorizedAccessException.

Appearently the Image control keeps the PNG locked so what we will do is get the file as a stream:

private async Task LoadImage() {
    var file = await ApplicationData.Current.LocalFolder.GetFileAsync("text.png");
    var stream = await file.OpenAsync(FileAccessMode.Read);
    var bitmapImage = new BitmapImage();
    await bitmapImage.SetSourceAsync(stream);
    image.Source = bitmapImage;
}

This will keep the PNG file unlocked and you can overwrite it as many times as you want. Windows 8.1 made it really easy to save XAML as a PNG and I hope this tutorial helped you!