Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The documentation for <a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.pixels%28v=VS.95%29.aspx" rel="nofollow">WritableBitmap.Pixels</a> states that the "format used by the Silverlight WriteableBitmap is ARGB32 (premultiplied RGB)". Perhaps then the live tiles expect a non-premultiplied pixel format.</p> <p>I could not find any API in Silverlight to change the format, but I think the method in this article might be what you need:</p> <p><a href="http://nokola.com/blog/post/2010/01/27/The-Most-Important-Silverlight-WriteableBitmap-Gotcha-Does-It-LoseChange-Colors.aspx" rel="nofollow">http://nokola.com/blog/post/2010/01/27/The-Most-Important-Silverlight-WriteableBitmap-Gotcha-Does-It-LoseChange-Colors.aspx</a></p> <p>Edit:</p> <p>From my testing it seems like the problem is with JPEG compression artifacts after all, since SaveJpeg saves files in JPEG format even if you name them with a .png extension.</p> <p>My example code below has a commented out call to MakeNonPremultiplied(bitmap.Pixels) that shows how you would call the filter to modify pixel format to non-premultiplied if you used some library to save it to a file format that works with transparencies and expects non-premultiplied format.</p> <pre><code>using System; using System.IO; using System.IO.IsolatedStorage; using System.Linq; using System.Windows; using System.Windows.Media.Imaging; using Microsoft.Phone.Shell; namespace LiveTilePlayground { public partial class LiveTileGenerator { /// &lt;summary&gt; /// Renders a FrameworkElement (control) to a bitmap /// the size of a live tile or a custom sized square. /// &lt;/summary&gt; /// &lt;param name="element"&gt;The element.&lt;/param&gt; /// &lt;param name="size"&gt; /// The size of the bitmap (in each dimension). /// &lt;/param&gt; /// &lt;returns&gt;&lt;/returns&gt; public static WriteableBitmap RenderBitmap( FrameworkElement element, double size = 173.0) { element.Measure(new Size(size, size)); element.Arrange(new Rect(0, 0, size, size)); return new WriteableBitmap(element, null); } /// &lt;summary&gt; /// Updates the primary tile with specific title and background image. /// &lt;/summary&gt; /// &lt;param name="title"&gt;The title.&lt;/param&gt; /// &lt;param name="backgroundImage"&gt;The background image.&lt;/param&gt; public static void UpdatePrimaryTile(string title, Uri backgroundImage) { ShellTile primaryTile = ShellTile.ActiveTiles.First(); StandardTileData newTileData = new StandardTileData { Title = title, BackgroundImage = backgroundImage }; primaryTile.Update(newTileData); } /// &lt;summary&gt; /// Saves the tile bitmap with a given file name and returns the URI. /// &lt;/summary&gt; /// &lt;param name="bitmap"&gt;The bitmap.&lt;/param&gt; /// &lt;param name="fileName"&gt;Name of the file.&lt;/param&gt; /// &lt;returns&gt;&lt;/returns&gt; public static Uri SaveTileBitmap( WriteableBitmap bitmap, string fileName) { //MakeNonPremultiplied(bitmap.Pixels); using (var store = IsolatedStorageFile.GetUserStoreForApplication()) { if (!store.DirectoryExists(@"Shared\ShellContent")) { store.CreateDirectory(@"Shared\ShellContent"); } using ( var stream = store.OpenFile( @"Shared\ShellContent\" + fileName, FileMode.OpenOrCreate)) { bitmap.SaveJpeg(stream, 173, 173, 0, 100); } } return new Uri( "isostore:/Shared/ShellContent/" + fileName, UriKind.Absolute); } /// &lt;summary&gt; /// Transforms bitmap pixels to a non-alpha premultiplied format. /// &lt;/summary&gt; /// &lt;param name="bitmapPixels"&gt;The bitmap pixels.&lt;/param&gt; public static void MakeNonPremultiplied(int[] bitmapPixels) { int count = bitmapPixels.Length; // Iterate through all pixels and // make each semi-transparent pixel non-premultiplied for (int i = 0; i &lt; count; i++) { uint pixel = unchecked((uint)bitmapPixels[i]); // Decompose ARGB structure from the uint into separate channels // Shift by 3 bytes to get Alpha double a = pixel &gt;&gt; 24; // If alpha is 255 (solid color) or 0 (completely transparent) - // skip this pixel. if ((a == 255) || (a == 0)) { continue; } // Shift 2 bytes and filter out the Alpha byte to get Red double r = (pixel &gt;&gt; 16) &amp; 255; // Shift 1 bytes and filter out Alpha and Red bytes to get Green double g = (pixel &gt;&gt; 8) &amp; 255; // Filter out Alpha, Red and Green bytes to get Blue double b = (pixel) &amp; 255; // Divide by normalized Alpha to get non-premultiplied values double factor = 256 / a; uint newR = (uint)Math.Round(r * factor); uint newG = (uint)Math.Round(g * factor); uint newB = (uint)Math.Round(b * factor); // Compose back to ARGB uint bitmapPixels[i] = unchecked((int)( (pixel &amp; 0xFF000000) | (newR &lt;&lt; 16) | (newG &lt;&lt; 8) | newB)); } } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload