Visually Located

XAML and GIS

Creating live tiles with WriteableBitmap and transparent backgrounds

Creating apps with live tiles is nothing new. Many apps have live tiles, there are built in APIs for creating live tiles. With the release of Windows Phone 8.1 there are new APIs for creating live tiles. But what happens when the tiles you are creating go beyond what is supported? One of the easiest ways to create live tiles is with the WriteableBitmap.

private static Uri GenerateTile(Control tileBackground, string fileName)
{
    fileName = Path.Combine("Shared", "ShellContent", fileName);
 
    using (var stream = IsolatedStorageFile.GetUserStoreForApplication().CreateFile(fileName))
    {
        tileBackground.Measure(new Size(tileBackground.Width, tileBackground.Height));
        tileBackground.Arrange(new Rect(0, 0, tileBackground.Width, tileBackground.Height));
        var bitmap = new WriteableBitmap(tileBackground, null);
        bitmap.SaveJpeg(stream, (int)tileBackground.Width, (int)tileBackground.Height, 0, 100);
    }
    return new Uri("isostore:/" + fileName, UriKind.Absolute);
}

I’ve been using the code above for a few years and it works great. I would always ensure that the control I created has the background set to be the accent brush

<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneAccentBrush}">

I never thought much about this code until I read a blog by Sanjay Sharma titled Transparent Live Tile For Windows Phone 8.1. The blog walks you through creating tile images with transparency. The blog title is a little misleading as it doesn’t talk about live tiles at all. But it got me thinking, how can I ensure that my apps live tiles do have transparency. So I set out to remove the Background from the controls I use for my tiles.

<Grid x:Name="LayoutRoot">

This did not work. So I thought I would try setting the background to Transparent.

<Grid x:Name="LayoutRoot" Background="Transparent">

No luck there either. Then I tried setting the background to x:Null. But no luck. I was pretty frustrated and thought using WriteableBitmap would not be a solution for making tiles with transparency. Luckily Andrej Tozon, was there to help me do a face-palm.

image

Of course! The way I’ve been saving the WriteableBitmap is with the SaveJpeg method. And of course jpeg’s do not support transparency. I remembered that Cimbalino from Pedro Lamas had a method to save a WritebaleBitmap as a png. So I added the Nuget pack and changed the save method for my GenerateTile method.

// Old:
// bitmap.SaveJpeg(stream, (int)tileBackground.Width, (int)tileBackground.Height, 0, 100);
 
// New using Cimbalino
bitmap.SavePng(stream);

And now my tiles always match the background the user chooses. If they change the accent color, it will match.

image

If they select a new background image for the start screen, the tile will be transparent so the image will show through!

image

Now my tiles will always match what the user wants!

blog comments powered by Disqus