Save Canvas as Image - UWP

Asked

Viewed 209 times

0

In applying UWP, I have the following canvas

<Canvas Name="Banner" Width="500" Background="Black" Height="200" Margin="334,53,-711,-156">
    <Image x:Name="img_Fita" HorizontalAlignment="Left" Height="30" Width="30" RenderTransformOrigin="10,2.36" Canvas.Left="38" Canvas.Top="31" />
    <Image x:Name="img_Insiginia" HorizontalAlignment="Left" Height="30" Width="30" RenderTransformOrigin="10,2.36" Canvas.Left="38" Canvas.Top="50" />
    <Image x:Name="img_Marca"  HorizontalAlignment="Left" Height="50" Width="88" RenderTransformOrigin="10,2.36" Canvas.Left="111" Canvas.Top="30"/>
</Canvas>

I use the following method to create an image from this canvas.

private async Task CreateSaveBitmapAsync(Canvas canvas)
{
        int width = 500;
        int height = 200;

        if (canvas != null)
        {
            RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
            await renderTargetBitmap.RenderAsync(canvas);

            var picker = new FileSavePicker();
            picker.FileTypeChoices.Add("JPEG Image", new string[] { ".jpg" });
            StorageFile file = await picker.PickSaveFileAsync();
            if (file != null)
            {
                var pixels = await renderTargetBitmap.GetPixelsAsync();

                using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                {
                    var encoder = await
                        BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
                    byte[] bytes = new byte[4 * width * height];

                    int index = 0;
                    for (int y = 0; y < height; ++y)
                        for (int x = 0; x < width; ++x)
                        {
                            bytes[index++] = 255;  // B
                            bytes[index++] = 255;  // G
                            bytes[index++] = 255;  // R
                            bytes[index++] = 255;  // A
                        }
                    encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                                         BitmapAlphaMode.Ignore,
                                         (uint)canvas.ActualWidth, (uint)canvas.ActualHeight,
                                         96, 96, bytes);

                    await encoder.FlushAsync();
                }
            }
        }
}

But instead of saving what’s in canvas, it simply saves a blank image. What may be going wrong?

1 answer

1


Well, after a few days researching, I managed to assemble a method that runs already on the save button, and does what I need.

   private async void Salvar_Click(object sender, RoutedEventArgs e)
    {
        RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
        await renderTargetBitmap.RenderAsync(Banner);
        var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();

        var savePicker = new FileSavePicker();
        savePicker.DefaultFileExtension = ".png";
        savePicker.FileTypeChoices.Add(".png", new List<string> { ".png" });
        savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
        savePicker.SuggestedFileName = txt_Nome_Personagem.Text + ".png";

        var saveFile = await savePicker.PickSaveFileAsync();

        if (saveFile == null)
            return;

        using (var fileStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream);

            encoder.SetPixelData(
                BitmapPixelFormat.Bgra8,
                BitmapAlphaMode.Straight,
                (uint)renderTargetBitmap.PixelWidth,
                (uint)renderTargetBitmap.PixelHeight,
                DisplayInformation.GetForCurrentView().LogicalDpi,
                DisplayInformation.GetForCurrentView().LogicalDpi,
                pixelBuffer.ToArray());

            await encoder.FlushAsync();
        }
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.