Windows Phone 7: Cutting Transparency Down To Size


Warning: Illegal string offset 'status_txt' in /homepages/30/d169642629/htdocs/brilliant/blog/wp-content/plugins/share-and-follow/share-and-follow.php on line 1093

Warning: Illegal string offset 'status_txt' in /homepages/30/d169642629/htdocs/brilliant/blog/wp-content/plugins/share-and-follow/share-and-follow.php on line 1093

Warning: Illegal string offset 'status_txt' in /homepages/30/d169642629/htdocs/brilliant/blog/wp-content/plugins/share-and-follow/share-and-follow.php on line 1105

Warning: Illegal string offset 'status_txt' in /homepages/30/d169642629/htdocs/brilliant/blog/wp-content/plugins/share-and-follow/share-and-follow.php on line 1132

Warning: Illegal string offset 'status_txt' in /homepages/30/d169642629/htdocs/brilliant/blog/wp-content/plugins/share-and-follow/share-and-follow.php on line 1093

Warning: Illegal string offset 'status_txt' in /homepages/30/d169642629/htdocs/brilliant/blog/wp-content/plugins/share-and-follow/share-and-follow.php on line 1122

I know that few developers these days give a second thought to such trivialities as application footprint, but as someone who lived through the DOS era I still get queasy when I know I’m wasting space. Now with the spotlight on mobile devices with (relatively) small drive and memory space, developers would once again be wise to watch their application weight. While even 8GB may seem like a lot for a smartphone device, with users using large music collections and high-definition video — not to mention hundreds of other apps — that space can quickly get eaten. Personally I chewed through half of my Samsung Focus’ storage the first time I plugged it into my PC and synced it to my Zune music collection…

It should come as no surprise then that when I realized 75% of my near 700KB xap file was images, an 8-bit version of Jiminy Cricket materialized on my shoulder and started to sadly shake it’s head. The culprit? Transparent images.

Image Format Primer

There are two primary image formats that have emerged over the years as standard for web and client applications: PNG and JPEG. PNG uses a lossless run-length encoding which makes it ideal for images don’t have a lot of colour variation. JPEG uses a fuzzy algorithm that compresses complex images like photos extremely well, but it’s lossy and causes visible artifacts depending on the compression level and image content. It’s usually pretty straightforward which format you should pick based on the image content, except for one major differentiator: transparency support. PNG has it but JPEG does not.

The Conundrum

I wanted my app to be pretty (because I like apps that look good) so I picked photo-quality images. For example, one of my images was a piece of note paper. The problem arose when I needed the images to have transparency. It was absolutely essential that they have slick drop-shadows and realistic looking edges when displayed on my equally pretty background. The inescapable conclusion was that I’d have to save them as PNG images, which in the case of my note paper resulted in 250KB for the 400×400 image… nearly half of my total application size!

It was at this point that Jiminy started threatening me with nipple clamps and wires connected to car batteries, so I hid in a closet and began to think of possible solutions. It turns out there’s a way to use both image formats for the things they’re good at: JPEG for image compression and PNG for transparency. By splitting the image into a separate content and transparency (alpha) images, I could actually reduce the images in total size by as much as 90%! The key is the UIElement.OpacityMask property.

First Thing’s First

Before we can do our XAML magic we first need to create our images. I like to use Adobe Photoshop, but other drawing packages should provide similar functionality. With your transparent image open, let’s split it into two:

Since it probably doesn’t require any changes, first we’ll create our content JPEG image. The one thing that is important is that the colours in your semi-transparent areas are what you need them to be. The alpha layer image won’t contain any colour information, so you need to tweak the image for that. If you’re using a simple drop-shadow or other effect that all the same colour, the Photoshop “Save for Web and Devices” feature will let you choose a matting colour when you export it (black for a drop-shadow, etc).

Next we need to create a layer that we’ll use to export our PNG transparency image. Right-click on the content layer and choose “Select Pixels”. This will create a selection area that exactly matches the alpha channel for that layer. Remember that PNG compresses best with less colours, so let’s go nuts and create a layer that’s all white. Exciting, huh? Choose “New Layer > Solid Color” and then choose white (or any colour you want) when the picker pops up. Since you had a selection, Photoshop will automatically add a layer mask for you which matches the content layer transparency. Make sure none of the content layers are showing and export the new layer to a PNG file.

You should now have two files which are hopefully smaller than the original PNG you started with. For my note paper graphic, the resulting JPEG image was a mere 20kb and the PNG mask a puny 10kb. That’s a total 220kb size reduction from the single PNG image… an 88% improvement!

XAML Me, Baby

Now on to Silverlight… Now somewhere in your code you should have a brush defined with your old image file:

<ImageBrush x:Key="MyBrush" Stretch="Fill"
    ImageSource="images/original.png"/>

Which we’re going to update and add a new brush to:

<ImageBrush x:Key="MyBrush" Stretch="Fill"
    ImageSource="images/new.jpg"/>

<ImageBrush x:Key="MyOpacityBrush" Stretch="Fill"
    ImageSource="images/new_alpha.png"/>

Now with our brushes added, we can update our UI elements. Here’s simple example using a Grid to simply display the masked image:

<Grid Background="{StaticResource MyBrush}"
  OpacityMask="{StaticResource MyOpacityBrush}"/>

Summary

If you’re using Silverlight for Windows Phone 7 and plan ¬†to use a lot of rich graphics, creative use of OpacityMask is an easy way to lower your storage and memory footprint

About Dan Drew

Dan has worked in the software industry for almost 15 years as a developer, architect and manager at industry leaders such as Delrina, Microsoft and MySpace. The results of his work are used by millions of users in the home, corporate, and Internet markets.
This entry was posted in Development, Software, Technology, Windows. Bookmark the permalink.

Comments are closed.