Reputation: 15091
I'm drawing some shapes onto the screen on my Windows Universal App and then I'm also trying to save the base UIElement into a file and assign my LiveTile template to use it.
I think I'm close, but something is very wrong. Here's how it looks on my screen:
And here is how it looks on the Tile:
The black in the first image is meant to be transparent, and the live tile seems to have a lot of transparent pixels (the light grey is my background image). I can see lots of yellow and green, so it seems to be correctly creating/finding the file and updating the live tile template. I just can't get it to look how I intended it to - on my Windows Phone.
However, on my Windows 10 desktop - it looks how I'd expect (only it seems to have lost it's transparency - which I'm happy enough with)
The Canvas is 150x150. The live tile template is TileSquare150x150Image. I'm using a .png file. I've tried changing the BitmapPixelFormat, manually setting the logicalDpi to use when calling encoder.SetPixelData, and using different BitmapAlphaModes...occasionally these throw exceptions, otherwise it seems to render about the same.
Can anyone nudge me in the right direction? I thought a Universal App would ensure the same behavior between devices, so I was very surprised to see it behaving so differently between the phone and desktop...but I'm sure I'm just doing something incorrectly. My code looks like this:
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();
}
Upvotes: 0
Views: 108
Reputation: 3580
When you're rendering a control using RenderTargetBitmap
, the image is automatically scaled by DisplayInformation.RawPixelsPerViewPixel
(even if you specify width and height in the RenderAsync()
call).
For this reason, you should always use the PixelWidth
and PixelHeight
properties of the RenderTargetBitmap
to determine the actual size of the image that was rendered.
The problem in the question is that options.Size.Width
and options.Size.Height
are not the same as the values from the RenderTargetBitmap
, and so the pixel data and the size of the image passed to the encoder do not match.
Upvotes: 2