Лучший способ рендеринга пользовательских живых плиток в фоновой задаче (C #) с помощью универсального приложения WP8.1?

#c# #c #windows-phone-8.1

#c# #c #windows-phone-8.1

Вопрос:

Я нахожусь в процессе переписывания своего приложения в модель универсального приложения, оптимизированную для Windows (Phone) 8.1.

Я создал свою фоновую задачу (C #), которая извлекает некоторые данные из внешних источников, и последним шагом является рендеринг пользовательских .PNG, который можно использовать в качестве плитки.

Ранее для Windows Phone 7.x и 8.0 я использовал стороннее приложение под названием TCD.Controls.LiveTiles.Свет, который поможет вам преобразовать пользовательские элементы управления XAML в .PNG. Это сработало безупречно, но, похоже, у него есть некоторые проблемы с совместимостью с моделью универсального приложения.

Теперь мне было интересно — каков наилучший способ создания.PNG в фоновой задаче?

Я читал о реализации на C XamlRenderingBackgroundTask и RenderTargetBitmap, но поскольку я не разбираюсь в C , а моя текущая задача уже на C #, я хочу использовать C #.

С уважением, Нильс Лаут

Комментарии:

1. Просто делайте то, что они делают в примере C , только на C #. 🙂 Я протестировал его, и, похоже, он работает нормально. Я не думаю, что память или процессорное время являются проблемой (их не было, когда я ее тестировал).

Ответ №1:

У меня была такая же проблема, но я нашел этот пример рендеринга PNG в C #. Я нашел это на https://social.msdn.microsoft.com/Forums/en-US/43295c90-43e8-4b08-8a25-958a1c3d0a0b/explanation-on-windowsuixamlmediaxamlrenderingbackgroundtask?forum=WindowsPhonePreviewSDK

 using System;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.Graphics.Imaging;
using Windows.UI.Notifications;
using Windows.Data.Xml.Dom;

namespace BackgroundTask
{
    public sealed class AppTileUpdater : XamlRenderingBackgroundTask
    {
        protected override void OnRun(Windows.ApplicationModel.Background.IBackgroundTaskInstance taskInstance)
        {
            BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();
            System.Diagnostics.Debug.WriteLine("OnRun called!");
            UpdateTileAsync(_deferral);
        }

        private async Task<string> ReadFile()
        {
            var folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
            var file = await folder.GetFileAsync("customTile.xml");
            string szCustomTileXML = await Windows.Storage.FileIO.ReadTextAsync(file);
            return szCustomTileXML;
        }
        private async void UpdateTileAsync(BackgroundTaskDeferral deferral)
        {

            var folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
            var file = await folder.GetFileAsync("customTile.xml");
            string szCustomTileXML = await Windows.Storage.FileIO.ReadTextAsync(file);

            Border tile = XamlReader.Load(szCustomTileXML) as Border;

            if (null != tile)
            {
                tile.Background = new SolidColorBrush(Windows.UI.Colors.Orange);
                Grid grid = tile.Child as Grid;
                TextBlock text = grid.FindName("Timestamp") as TextBlock;
                text.Text = DateTime.Now.ToString("hh:mm:ss");
                text = grid.FindName("TimeZone") as TextBlock;
                text.Text = TimeZoneInfo.Local.DisplayName;

                Image logo = grid.FindName("LogoImage") as Image;
                var img = new BitmapImage() { CreateOptions = BitmapCreateOptions.None };
                img.UriSource = new Uri("ms-appx:///Assets/acorn.png");

                RenderTargetBitmap rtb = new RenderTargetBitmap();
                await rtb.RenderAsync(tile, 150, 150);
                IBuffer pixels = await rtb.GetPixelsAsync();
                DataReader dReader = Windows.Storage.Streams.DataReader.FromBuffer(pixels);
                byte[] data = new byte[pixels.Length];
                dReader.ReadBytes(data);

                var outputFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.CreateFileAsync("UpdatedLiveTile.png", Windows.Storage.CreationCollisionOption.ReplaceExisting);
                var outputStream = await outputFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
                BitmapEncoder enc = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, outputStream);
                enc.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)rtb.PixelWidth, (uint)rtb.PixelHeight, 96,96, data);
                await enc.FlushAsync();                
            }
            var TileMgr = TileUpdateManager.CreateTileUpdaterForApplication();
            TileMgr.Clear();
            var tileTemplate = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150Image);
            var tileImageAttributes = tileTemplate.GetElementsByTagName("image");
            XmlElement tmp = tileImageAttributes[0] as XmlElement;
            tmp.SetAttribute("src", "UpdatedLiveTile.png");
            var notification = new TileNotification(tileTemplate);
            TileMgr.Update(notification);
            deferral.Complete();
        }

        public void Run(IBackgroundTaskInstance taskInstance)
        {
            System.Diagnostics.Debug.WriteLine("Run called!");
            OnRun(taskInstance);
        }
    }
}
  

Ответ №2:

На данный момент наиболее эффективным способом является использование Win2D Framework и пошаговое рисование растрового изображения. Такой подход позволит сохранить ваши ресурсы свободными.

Комментарии:

1. Есть примеры того, как это сделать?