Transforming SVG graphics to XAML Metro Icons

This short article shows how to pimp your Windows 8 Metro apps with native XAML icons that are created from W3C Scalable Vector Graphics. SVG graphics are XML documents, and hence should be easily translatable into an other XML schema, such as XPS (the technology formerly known as ... Metro). Just like Metro XAML, XPS is a subset of XAML. Unfortunately its full object model is not implemented in Silverlight or Metro. In Windows, since the-OS-that-should-not-be-named, XPS is also used as print spooler format. This means that you don't even have to write an XSLT transformation to translate SVG to XAML: let the printer driver do the heavy lifting.

Here's how it goes.

Find a graphic

Grab a designer, or navigate to your favorite source of royalty free images - such as The Noun Project.

Download the resource, as SVG:

Transform it to XPS

Open the SVG file in your browser, and print to an XPS file through the Microsoft XPS Document Writer:

Find XAML Payload

The XPS document is actually a ZIP-file. So just add .zip to its name:

The XPS document contains page layout, headers, footers, embedded fonts, and so on. It also contains all left-overs from the tools that created the SVG. Not all SGV graphics are lean and mean on the inside. Some of the XML reminds me to the tons of obsolete HTML that used to be generated by Microsoft FrontPage. Anyway, you just have to find the place where the payload -the graphic- is hidden. It's most probably part of the first page of the first document, so \Documents\1\Pages\1.fpage would be the first place to look:

Bingo! Here's the XAML that we're looking for - the one with all the PATH elements:

Clean up XAML

If you just copy/paste that bunch of Canvas elements from the FixedPage into a Grid in a Metro app, the Visual Studio XAML Designer may already recognize it and start displaying the icon. The very first Canvas on the page is probably the page boundary, so you may delete it. The Glyphs elements can also be removed. The now remaining Path elements are most probably the translated SVG. All you need to do is throw these in a Viewbox, like this Planet SVG:

<Viewbox>
	<Grid
		VerticalAlignment="Center"
		HorizontalAlignment="Center">
	<Path
		Data="F 1 M 46.857,18.462 C 29.654,18.462 15.658,32.457 15.658,49.66 15.658,66.863 29.654,80.858 46.857,80.858 64.06,80.858 78.056,66.863 78.056,49.66 78.056,32.457 64.06,18.462 46.857,18.462 Z M 46.857,74.819 C 32.983,74.819 21.697,63.534 21.697,49.66 21.697,35.787 32.984,24.5 46.857,24.5 60.73,24.5 72.018,35.787 72.018,49.66 72.018,63.534 60.73,74.819 46.857,74.819 Z"
		Fill="Gold" />
	<Path
		Data="F 1 M 80.782,42.622 C 81.339,44.794 81.26,47.228 81.091,49.701 89.277,54.928 90.683,58.083 90.625,58.6 90.613,58.619 89.058,60.471 80.095,59.816 75.472,59.477 69.955,58.53 64.001,57.09 64.001,57.109 64.003,57.125 64.003,57.144 64.003,59.188 63.462,61.105 62.524,62.772 68.841,64.302 74.719,65.31 79.666,65.673 89.301,66.377 94.692,64.71 96.152,60.574 98.181,54.833 90.748,48.331 80.782,42.622 Z"
		Fill="Gold" />
	<Path
		Data="F 1 M 43.045,50.566 C 33.593,46.987 25.045,42.873 18.653,38.804 10.379,33.539 8.963,30.361 9.021,29.84 9.033,29.821 10.344,27.84 19.296,28.492 20.495,26.281 22.416,24.499 24.4,23.092 23.142,22.943 21.311,22.865 19.983,22.768 10.347,22.063 4.953,23.73 3.493,27.866 1.934,32.281 5.624,37.325 14.774,43.291 21.589,47.733 30.796,52.21 41.022,56.078 41.211,54.04 41.932,52.158 43.045,50.566 Z"
		Fill="Gold" />
	<Path
		Data="M 44.509,57.291 C 44.509,52.9832 48.0012,49.491 52.309,49.491 L 52.309,49.491 C 56.6168,49.491 60.109,52.9832 60.109,57.291 L 60.109,57.291 C 60.109,61.5988 56.6168,65.091 52.309,65.091 L 52.309,65.091 C 48.0012,65.091 44.509,61.5988 44.509,57.291 Z"
		Fill="Goldenrod" />
	</Grid>
</Viewbox>

 Oh wait, there's an easier way

If that's too cumbersome, you can also upload your SVG to Graphspe's on-line SVG to XAML Converter. That's what I did with Andrew Forrester's awesome Death Star graphic, also from the Noun Project:

It directly returns the Canvas with the Path. Just drop it in a ViewBox:

<Viewbox>
	<Path
	Fill="#FF000000"
	Data="F1 M50.844,1.04L50.844,1.04 50.844,1.04C50.741,1.039 50.64,1.03 50.54,1.023 50.35,1.009 50.159,0.997 49.965,0.997 22.863,0.997 0.813999999999993,23.045 0.813999999999993,50.146 0.813999999999993,77.248 22.863,99.295 49.965,99.295 50.156,99.295 50.344,99.283 50.531,99.27 50.633,99.263 50.735,99.254 50.838,99.253 50.84,99.253 50.842,99.253 50.845,99.253 77.461,98.778 99.115,76.748 99.115,50.146 99.115,23.54 77.461,1.511 50.844,1.04z M58.051,94.223C58.466,93.766,58.868,93.299,59.271,92.833L59.538,92.525C59.749,92.283 59.959,92.042 60.163,91.795 60.63,91.23 61.077,90.65 61.523,90.071L61.785,89.737C61.94,89.542 62.094,89.346 62.242,89.147 62.835,88.349 63.429,87.507 64.01,86.643L64.176,86.406C64.77,85.516 65.369,84.565 65.957,83.578 66.073,83.383 66.184,83.184 66.293,82.986L66.509,82.603C66.902,81.916 67.258,81.293 67.593,80.659 67.732,80.394 67.864,80.129 67.996,79.861L68.192,79.468C68.493,78.869 68.793,78.27 69.075,77.663 69.236,77.314 69.389,76.965 69.542,76.615L69.65,76.368C69.908,75.779 70.165,75.189 70.406,74.593 70.578,74.166 70.741,73.737 70.904,73.305 71.153,72.648 71.372,72.055 71.578,71.456 71.738,70.994 71.891,70.528 72.041,70.061 72.233,69.462 72.416,68.862 72.591,68.256 72.728,67.784 72.861,67.313 72.987,66.837 73.149,66.225 73.3,65.608 73.444,64.991L73.474,64.859C73.575,64.4289999999999 73.674,64.0009999999999 73.765,63.569 73.898,62.934 74.016,62.297 74.13,61.657L74.192,61.317C74.255,60.965 74.32,60.6139999999999 74.376,60.261 74.477,59.617 74.559,58.971 74.641,58.323L74.7,57.85C74.74,57.539 74.781,57.23 74.813,56.918 74.891,56.172 74.945,55.419 74.997,54.667L75.028,54.261C75.049,54.023 75.068,53.784 75.081,53.545 75.143,52.348 75.173,51.236 75.173,50.146 75.173,48.35 75.088,46.469 74.921,44.544 75.592,44.415 76.253,44.229 76.923,43.985 82.302,42.016 85.113,36.683 83.919,30.715 82.993,26.089 79.793,21.875 75.356,19.444 72.966,18.133 70.406,17.441 67.954,17.441 67.457,17.441 66.953,17.472 66.429,17.537 66.207,17.151 65.983,16.767 65.752,16.387L65.313,15.678C64.986,15.15 64.653,14.627 64.31,14.11 64.14,13.854 63.97,13.599 63.797,13.346 63.443,12.826 63.08,12.311 62.711,11.801L62.248,11.161C61.722,10.451,61.185,9.751,60.63,9.063L60.543,8.959C59.98,8.267 59.456,7.649 58.922,7.04 58.922,7.04 58.154,6.184 58.051,6.07 79.202,9.94 94.814,28.407 94.814,50.146 94.814,71.882 79.201,90.349 58.051,94.223z M70.433,23.951C70.373,24.042 70.322,24.138 70.265,24.231 70.05,24.581 69.853,24.94 69.672,25.309 69.613,25.428 69.553,25.546 69.498,25.667 69.29,26.125 69.102,26.592 68.946,27.074 68.944,27.08 68.94,27.086 68.938,27.093 68.846,27.075 68.752,27.072 68.66,27.059 68.476,27.029 68.296,27.011 68.117,27.007 68.104,27.007 68.093,27.004 68.08,27.004 68.073,27.004 68.068,27.006 68.061,27.006 67.248,26.997 66.506,27.244 65.908,27.695 65.88,27.716 65.853,27.738 65.827,27.76 65.642,27.907 65.469,28.068 65.317,28.253 64.6489999999999,29.065 64.3939999999999,30.177 64.6169999999999,31.307 64.671,31.574 64.7499999999999,31.833 64.8489999999999,32.084 64.8819999999999,32.168 64.9289999999999,32.245 64.9669999999999,32.326 65.0429999999999,32.489 65.1159999999999,32.651 65.2089999999999,32.805 65.2649999999999,32.897 65.3329999999999,32.979 65.395,33.067 65.488,33.199 65.578,33.333 65.682,33.456 65.756,33.543 65.84,33.62 65.919,33.702 66.026,33.812 66.133,33.924 66.25,34.024 66.339,34.101 66.436,34.167 66.529,34.237 66.6499999999999,34.327 66.7689999999999,34.416 66.896,34.495 66.998,34.558 67.104,34.61 67.209,34.665 67.34,34.733 67.471,34.801 67.606,34.857 67.717,34.903 67.831,34.939 67.945,34.976 68.084,35.021 68.222,35.063 68.364,35.096 68.482,35.122 68.6,35.14 68.72,35.157 68.805,35.169 68.887,35.194 68.973,35.2 69.013,35.324 69.064,35.443 69.108,35.565 69.151,35.684 69.194,35.802 69.24,35.919 69.39,36.303 69.553,36.682 69.738,37.048 69.745,37.061 69.751,37.075 69.757,37.088 69.95,37.467 70.167,37.832 70.395,38.19 70.458,38.29 70.525,38.387 70.59,38.485 70.78,38.767 70.982,39.041 71.194,39.308 71.253,39.382 71.307,39.458 71.368,39.531 71.637,39.855 71.92,40.165 72.219,40.462 72.287,40.53 72.361,40.594 72.431,40.661 72.675,40.894 72.929,41.118 73.191,41.332 73.286,41.409 73.379,41.485 73.475,41.56 73.54,41.61 73.601,41.665 73.667,41.715 73.574,41.726 73.481,41.724 73.388,41.732 73.381,41.733 73.373,41.733 73.367,41.733 73.119,41.754 72.87,41.778 72.622,41.778 72.029,41.778 71.439,41.717 70.853,41.625 65.531,40.788 60.681,36.31 59.601,30.913 59.029,28.053 59.606,25.389 61.226,23.413 61.947,22.534 62.845,21.847 63.868,21.349 64.612,20.987 65.424,20.732 66.289,20.588 66.292,20.588 66.295,20.588 66.298,20.587 66.832,20.499 67.383,20.443 67.954,20.443 69.455,20.443 71.022,20.778 72.554,21.42 72.493,21.476 72.444,21.542 72.384,21.599 72.089,21.882 71.809,22.178 71.543,22.485 71.468,22.572 71.389,22.655 71.315,22.744 70.998,23.129 70.703,23.532 70.433,23.951z M70.87,31.674C70.871,31.75 70.863,31.822 70.854,31.895 70.851,31.93 70.85,31.965 70.844,31.999 70.807,32.206 70.731,32.394 70.614,32.557 70.387,32.873 70.017,33.081 69.57,33.142 69.568,33.142 69.567,33.143 69.565,33.143 69.563,33.143 69.561,33.143 69.559,33.143 69.455,33.158 69.359,33.184 69.324,33.213 68.086,33.213 66.829,32.159 66.579,30.915 66.471,30.37 66.571,29.875 66.862,29.521 67.136,29.187 67.569,29.002 68.08,29.002 68.156,29.002 68.232,29.018 68.309,29.025 68.571,29.066 68.858,29.152 69.175,29.306 69.175,29.306 69.176,29.306 69.176,29.307 69.807,29.615 70.315,30.113 70.605,30.676 70.614,30.695 70.625,30.712 70.633,30.731 70.722,30.914 70.789,31.102 70.829,31.294 70.829,31.296 70.83,31.299 70.831,31.302 70.856,31.43 70.867,31.554 70.87,31.674z" />
</Viewbox>

The result

Just look at these shiny tiles:

Enjoy!