c# – SaveJpeg导致具有透明度的“阴影”瑕疵
只是想跟你检查一件事.我正在使用WriteableBitmap创建一个我作为实时图块的图像.工作正常,但我注意到文本边缘有阴影.使文本看起来有点脏或凌乱.
看看下面的图片.左侧部分来自使用WriteableBitmap创建的实时磁贴,右侧部分是Windows Phone标准磁贴(Internet Explorer磁贴).看到不同? http://img268.imageshack.us/img268/8749/unled2imo.png http://img268.imageshack.us/img268/8749/unled2imo.png 我能做些什么吗?你以前注意到了吗? 编辑: string sIsoStorePath = @"SharedShellContenttile.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来更改格式,但我认为本文中的方法可能就是您所需要的: http://nokola.com/blog/post/2010/01/27/The-Most-Important-Silverlight-WriteableBitmap-Gotcha-Does-It-LoseChange-Colors.aspx 编辑: 从我的测试来看,似乎问题在于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(@"SharedShellContent")) { store.CreateDirectory(@"SharedShellContent"); } using ( var stream = store.OpenFile( @"SharedShellContent" + 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)); } } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |