只是想跟你检查一件事.我正在使用WriteableBitmap创建一个我作为实时图块的图像.工作正常,但我注意到文本边缘有阴影.使文本看起来有点脏或凌乱.
看看下面的图片.左侧部分来自使用WriteableBitmap创建的实时磁贴,右侧部分是Windows Phone标准磁贴(Internet Explorer磁贴).看到不同?
我能做些什么吗?你以前注意到了吗?
编辑:
嗯,我想我正在看错了功能.我认为可能是导致这种情况的wbmp.SaveJpeg?我将文本和背景图像放入网格,然后使用wbmp.SaveJpeg保存.这是什么原因?任何解决方法?
string sIsoStorePath = @"\Shared\ShellContent\tile.png"; using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication()) { //ensure directory exists String sDirectory = System.IO.Path.GetDirectoryName(sIsoStorePath); if (!appStorage.DirectoryExists(sDirectory)) { appStorage.CreateDirectory(sDirectory); } using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(sIsoStorePath,System.IO.FileMode.Create,appStorage)) { wbmp.SaveJpeg(stream,173,100); } }
解决方法
WritableBitmap.Pixels的文档指出“Silverlight WriteableBitmap使用的格式是ARGB32(预乘RGB)”.也许那时的实时图块需要非预乘的像素格式.
我在Silverlight中找不到任何API来更改格式,但我认为本文中的方法可能就是您所需要的:
编辑:
从我的测试来看,似乎问题在于JPEG压缩工件,因为即使你用.png扩展名命名,SaveJpeg也会以JPEG格式保存文件.
下面我的示例代码对MakeNonPremultiplied(bitmap.Pixels)进行了注释调用,该调用显示了如果使用某个库将其保存为与透明度一起使用的文件格式,您将如何调用过滤器将像素格式修改为非预乘.非预乘格式.
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 { /// <summary> /// Renders a FrameworkElement (control) to a bitmap /// the size of a live tile or a custom sized square. /// </summary> /// <param name="element">The element.</param> /// <param name="size"> /// The size of the bitmap (in each dimension). /// </param> /// <returns></returns> public static WriteableBitmap RenderBitmap( FrameworkElement element,double size = 173.0) { element.Measure(new Size(size,size)); element.Arrange(new Rect(0,size,size)); return new WriteableBitmap(element,null); } /// <summary> /// Updates the primary tile with specific title and background image. /// </summary> /// <param name="title">The title.</param> /// <param name="backgroundImage">The background image.</param> public static void UpdatePrimaryTile(string title,Uri backgroundImage) { ShellTile primaryTile = ShellTile.ActiveTiles.First(); StandardTileData newTileData = new StandardTileData { Title = title,BackgroundImage = backgroundImage }; primaryTile.Update(newTileData); } /// <summary> /// Saves the tile bitmap with a given file name and returns the URI. /// </summary> /// <param name="bitmap">The bitmap.</param> /// <param name="fileName">Name of the file.</param> /// <returns></returns> 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,100); } } return new Uri( "isostore:/Shared/ShellContent/" + fileName,UriKind.Absolute); } /// <summary> /// Transforms bitmap pixels to a non-alpha premultiplied format. /// </summary> /// <param name="bitmapPixels">The bitmap pixels.</param> 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 < 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 >> 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 >> 16) & 255; // Shift 1 bytes and filter out Alpha and Red bytes to get Green double g = (pixel >> 8) & 255; // Filter out Alpha,Red and Green bytes to get Blue double b = (pixel) & 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 & 0xFF000000) | (newR << 16) | (newG << 8) | newB)); } } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。