I have talked about how to create custom live tile in Windows Phone practical development skills (17): tile for custom applications. Today let's dig a little bit deeper.
What do you see in this image shown below?
Do you see the same tile with different background called accent color in Windows Phone. so how can we create such tile. one simplest way is we replace applicationicon.png with a transparent PNG file. but as we know it is just main Tile of our app. can we create own tile since we can pin what we want to start?
Yes, we can do that. All we need to do is to create a transparent PNG file and save it to isolated.
Maybe you have already know, we can save JPG file to ISO with following code:
WriteablebitmapBit =NewWriteablebitmap(); Bit. savejpeg (stream, 480,800, 0,100 );
Or
Extensions. Savejpeg (Writeablebitmap, Stream, 480,800, 0,100 );
But JPG can not be transparent. So we need some extra library to help us create transparent PNG images. Here I use the famous open Souce imagetools.
We can use two differernt ways to dynamic create images. One way I have post here.
// Add encoder for PNG Image Encoders . Addencoder < Pngencoder > ();Standardtiledata STD = New Standardtiledata {Backgroundimage = New Uri (Createbackground (), Title = "Tile test" , Backtitle = "Secondary" , Backbackgroundimage = New Uri (Createbackground ())}; Shelltile . Create ( New Uri ("/Mainpage. XAML? Type = 1" , Urikind . Relative), STD); Sw. Stop (); Debug . Writeline ( "Tranditonal method took time :" + Sw. elapsedmilliseconds );
Here is createbackground method looks like:
Public static string Createbackground (){ Grid Grid = New Grid {Background = New Imagebrush {Imagesource = New Bitmapimage {Urisource = New Uri ( "/Mangtile; component/images/1.png" , Urikind . Relative), createoptions = Bitmapcreateoptions . Ignoreimagecache }}, width = 173, Height = 173 }; Textblock TB = New Textblock {Text = "Hello World" , Foreground = New Solidcolorbrush ( Colors . Red), fontsize = 32,}; grid. Children. Add (TB); grid. Arrange ( New Rect (0 d, 0 d, 173,173 )); Writeablebitmap Wbmp = New Writeablebitmap (Grid, Null ); Extendedimage Extendimage = wbmp. toimage (); Using ( VaR Store = Isolatedstoragefile . Getuserstoreforapplication ()){ If (! Store. directoryexists (tiledirectory) {store. createdirectory (tiledirectory );} Using ( VaR Stream = store. openfile (fullpath, system. Io. Filemode . Openorcreate) {extendimage. writetostream (stream, fullpath );}} Return "Isostore :/" + Fullpath ;}
And as we run it we can see what shown below:
Another way is just render it within imageopened event:
Public static void Createtile (Uri Imageuri, String Temperature, String Timeofday ){ VaR Source = New Bitmapimage (Imageuri) {createoptions = Bitmapcreateoptions . Ignoreimagecache ,}; String Fullpath = tiledirectory + @"/" + Timeofday + ". PNG" ; // This is important. The image can't be rendered before it's loaded. Source. imageopened + = (sender, e) => { // Create our image as a control, so it can be rendered to the writeablebitmap. VaR Cloudimage = New Image {Source = source, width = 173, Height = 173 }; // Textblock for the time of the day. Textblock Tbtemperature = New Textblock {Text = temperature + '°' , Fontsize = 36, foreground = New Solidcolorbrush ( Colors . White), fontfamily = New Fontfamily ( "Segoe WP" ),}; Using ( Isolatedstoragefile Store = Isolatedstoragefile . Getuserstoreforapplication ()){ If (! Store. directoryexists (tiledirectory) {store. createdirectory (tiledirectory );} VaR Bitmap =New Writeablebitmap (173,173 ); // Render our background. Remember the renders are in the same order as XAML, // so whatever is rendered first, is rendered behind the next element. // render our cloud image Bitmap. Render (cloudimage, New Translatetransform ()); // Render the temperature text. Bitmap. Render (tbtemperature, New Translatetransform () {X = 124, y = 63}); bitmap. invalidate ();Extendedimage Extendimage = bitmap. toimage (); Using ( VaR Stream = store. openfile (fullpath, system. Io. Filemode . Openorcreate) {extendimage. writetostream (stream, fullpath );} Standardtiledata STD = New Standardtiledata {Backgroundimage = New Uri ( "Isostore :/" + Fullpath), Title ="Tile test22" , Backtitle = "Secondary" , Backbackgroundimage = New Uri ( "Isostore :/" + Fullpath )}; Shelltile . Create ( New Uri ( "/Mainpage. XAML? Type = 2" , Urikind . Relative), STD );}};}
I have a test on it (conculsion is prefer to use second way as it's faster and more stable! )
Tranditonal took 239 MS, image size 6.11kb
Render took 10 MS, image size 5.24kb.
You can find demo source code here. Hope that helps ,.