2015-03-08 4 views
0

Я рисую некоторые фигуры на экране в своем Windows Universal App, а затем я также пытаюсь сохранить базовый UIElement в файл и назначить свой LiveTile шаблон для его использования.Создание образа LiveTile - выглядит хорошо на экране - выглядит не так, как LiveTile

Я думаю, что я рядом, но что-то очень не так. Вот как это выглядит на моем экране: How it appears on screen

А вот как это выглядит на плитке:

How it appears on start screen

черный на первом изображении предназначается, чтобы быть прозрачным, а живая плитка кажется иметь много прозрачных пикселей (светло-серый - это мое фоновое изображение). Я могу видеть много желтого и зеленого цветов, поэтому кажется, что вы правильно создаете/находите файл и обновляете шаблон живой плитки. Я просто не могу заставить его посмотреть, как я намеревался это сделать - на моем Windows Phone.

Однако, на моем рабочем столе Windows 10 - это выглядит так, как я ожидал (только он, кажется, потерял это прозрачность - что я достаточно с счастливым) On my desktop

холст 150x150. Шаблон для живой плитки - TileSquare150x150Image. Я использую файл .png. Я попытался изменить BitmapPixelFormat, вручную установив логическийDpi для использования при вызове encoder.SetPixelData и с использованием разных BitmapAlphaModes ... иногда эти исключения бросают, в противном случае, похоже, они будут отображаться примерно одинаково.

Может ли кто-нибудь подтолкнуть меня в правильном направлении? Я думал, что универсальное приложение обеспечит одинаковое поведение между устройствами, поэтому я был очень удивлен, увидев, что он ведет себя так по-разному между телефоном и рабочим столом ... но я уверен, что просто делаю что-то неправильно. Мой код выглядит следующим образом:

var renderBitMap = new RenderTargetBitmap(); 
await renderBitMap.RenderAsync(_container); 

var pixels = await renderBitMap.GetPixelsAsync();    
byte[] myBytes = pixels.ToArray(); 

var folder = ApplicationData.Current.LocalFolder; 
var file = await folder.CreateFileAsync("ts150.png", CreationCollisionOption.ReplaceExisting); 
var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi; 
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite)) 
{ 
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream); 
    encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)options.Size.Width, (uint)options.Size.Height, logicalDpi, logicalDpi, myBytes); 

    await encoder.FlushAsync(); 
} 
+2

Вы должны вызывать 'SetPixelData()' с помощью renderBitMap.PixelWidth/Height вместо тех, которые вы получаете из этой переменной 'options'. Я сомневаюсь, что они одинаковы. 'RenderAsync()' масштабирует изображение на основе значения 'DisplayInformation.RawPixelsPerViewPixel'. – yasen

+0

@yasen - Спасибо. Это полностью решило мою проблему. Если вы хотите опубликовать это как ответ - я бы принял его. Еще раз спасибо! –

ответ

2

Когда вы рендеринга управления с помощью RenderTargetBitmap, изображение автоматически масштабируется DisplayInformation.RawPixelsPerViewPixel (даже если указать ширину и высоту в RenderAsync() вызова).

По этой причине вы всегда должны использовать свойстваи PixelHeight свойств RenderTargetBitmap, чтобы определить фактический размер изображения, которое было визуализировано.

Проблема в том, что вопрос options.Size.Width и options.Size.Height не то же самое, как значения от RenderTargetBitmap, и таким образом, данные пикселя и размер изображения, переданного кодера не совпадают.

Смежные вопросы