blagnom650
blagnom650

Reputation: 47

Image being saved from canvas is not rendered properly

I'm trying to use the following code to save the contents of myCanvas as an image file in the gallery (for Windows Phone 8.1, not Silverlight). When I run the App, the image is saved but it is distorted. What am I doing wrong? I have uploaded the resultant image and the expected result.

enter image description here

public async void SaveFileToPhone()
  {
      var file = await KnownFolders.PicturesLibrary.CreateFileAsync("bug.png", CreationCollisionOption.GenerateUniqueName);

     await SaveVisualElementToFile(myCanvas, file);          
  }

async Task SaveVisualElementToFile(FrameworkElement element, StorageFile file)
{
    var renderTargetBitmap = new RenderTargetBitmap();
    await renderTargetBitmap.RenderAsync(element, (int)element.Width, (int)element.Height);
    var pixels = await renderTargetBitmap.GetPixelsAsync();
    txt_bug.Text = "Width: " + (int)element.Width + " Height:" + (int)element.Height;

    using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        var encoder = await
            BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
        byte[] bytes = pixels.ToArray();

        encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                             BitmapAlphaMode.Ignore,
                             (uint)element.Width, (uint)element.Height,
                             96, 96, bytes);

        await encoder.FlushAsync();
    }
}

The XAML code for canvas is as follows:

<Canvas x:Name="myCanvas" Background="#FF33FFE3" Margin="25,75,26,10" 
ManipulationStarted="myCanvas_ManipulationStarted" 
ManipulationCompleted="myCanvas_ManipulationCompleted" 
ManipulationDelta="myCanvas_ManipulationDelta" ManipulationMode="All" 
Tapped="myCanvas_Tapped" MinHeight="555" MinWidth="350" Width="350" Height="555">
    <Canvas.Clip>
        <RectangleGeometry Rect="0 0 350 555"/>
    </Canvas.Clip>
</Canvas>

Upvotes: 3

Views: 309

Answers (1)

kennyzx
kennyzx

Reputation: 12993

The params to the SetPixelData method are incorrect.

encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                         BitmapAlphaMode.Ignore,
                         (uint)element.Width, (uint)element.Height,
                         96, 96, bytes);

Change them to the follow can make it work.

encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                BitmapAlphaMode.Ignore,
                (uint)renderTargetBitmap.PixelWidth,
                (uint)renderTargetBitmap.PixelHeight,
                DisplayInformation.GetForCurrentView().LogicalDpi,
                DisplayInformation.GetForCurrentView().LogicalDpi,
                bytes);

You can download the XAML render to bitmap sample from MSDN for reference.

Upvotes: 3

Related Questions