4

一つ確認したいことがあります。WriteableBitmap を使用して、ライブ タイルとしての画像を作成しています。正常に動作しますが、テキストの端に影ができていることに気付きました。テキストを少し汚いまたは乱雑に見せます。

下の画像を見てください。左側の部分は WriteableBitmap を使用して作成されたライブ タイルからのもので、右側の部分は Windows Phone の標準タイル (Internet Explorer タイル) です。違いを見ます?

http://img268.imageshack.us/img268/8749/unled2imo.png http://img268.imageshack.us/img268/8749/unled2imo.png

これについて私にできることはありますか?前にこれに気づいたことがありますか?

編集:うーん、私は間違った関数を見ていると思います。これを引き起こしているのは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, 173, 0, 100);
    }
}
4

2 に答える 2

1

WritableBitmap.Pixelsのドキュメントには、「Silverlight WriteableBitmap で使用される形式は ARGB32 (乗算済み RGB) である」と記載されています。おそらく、ライブ タイルは事前に乗算されていないピクセル形式を想定しています。

フォーマットを変更するための API が Silverlight に見つかりませんでしたが、この記事の方法が必要な場合があると思います。

http://nokola.com/blog/post/2010/01/27/The-Most-Important-Silverlight-WriteableBitmap-Gotcha-Does-It-LoseChange-Colors.aspx

編集:

私のテストでは、.png 拡張子を付けて名前を付けたとしても、SaveJpeg はファイルを JPEG 形式で保存するため、結局のところ問題は 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, 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, 173, 173, 0, 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));
            }
        }
    }
}
于 2011-11-12T14:52:55.690 に答える
0

私はまったく同じ問題を抱えていましたが、私にとっての簡単な答えは、使用されている透過PNGを確認することでした. 16 ビットの色深度を使用するように設定されました。PNGを8ビットの色深度に変更すると、問題が解決しました。

于 2012-03-09T10:00:27.733 に答える