简体   繁体   中英

Saving Canvas to Image File saves Blank Black Image

For starters, I'm still new with UWP and XAML. I've made a simple code on my uwp where I have a canvas (named it "ImageHolder") and there is an image and textblock inside it. My main problem is that whenever I try to use RenderTargetBitmap inorder to save the canvas into an image file, it outputs a black blank image. Here is my XAML code:

<Page
x:Class="SaveAndRetreiveMap.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SaveAndRetreiveMap"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d">

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Line x:Name="dot" Stroke="Black" StrokeThickness="5" Fill="Black"></Line>

    <TextBox x:Name="xValue" HorizontalAlignment="Left" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Margin="89,415,0,0" Background="Azure"/>
    <TextBox x:Name="yValue" HorizontalAlignment="Left" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Margin="89,452,0,0" Background="Azure"/>
    <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="55,420,0,0" TextWrapping="Wrap" Text="X:" VerticalAlignment="Top" FontSize="20"/>
    <TextBlock x:Name="textBlock_Copy" HorizontalAlignment="Left" Margin="55,455,0,0" TextWrapping="Wrap" Text="Y:" VerticalAlignment="Top" FontSize="20"/>
    <Button x:Name="PlotButton" Content="Plot Points" HorizontalAlignment="Left" Margin="62,496,0,0" VerticalAlignment="Top" Click="PlotButton_Click"/>

    <Canvas Name="ImageHolder"  Height="206" Width="226" Margin="356,160,918,634">

        <Image x:Name="image" HorizontalAlignment="Left" Height="206" VerticalAlignment="Top" Width="226"/>
        <TextBlock Text="Johnny!" Margin="44,89,-44,-89"></TextBlock>
        <Button x:Name="button" Content="Save" HorizontalAlignment="Left" VerticalAlignment="Top" Click="button_Click" Canvas.Left="-133" Canvas.Top="335"/>
    </Canvas>
</Grid>

My CS code:

        private async void button_Click(object sender, RoutedEventArgs e)
        {
        RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
        await renderTargetBitmap.RenderAsync(ImageHolder);

        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 = pixels.ToArray();
                encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                                     BitmapAlphaMode.Ignore,
                                     (uint)ImageHolder.Width, (uint)ImageHolder.Height,
                                     96, 96, bytes);

                await encoder.FlushAsync();
            }
        }
    }

Output

输出量

I'm still really new at UWP, and a small help would really be appreciated. :)

It is due to your foreground is black you this is rendering black background, this will work --

FOR JPEG

XAML

<Canvas Name="ImageHolder" Height="260" Width="260">
        <Canvas.Background>
            <SolidColorBrush Color="White"/>
        </Canvas.Background>

        <Image x:Name="image" HorizontalAlignment="Left" Height="206" VerticalAlignment="Top" Width="226"/>
        <TextBlock Text="Johnny!" Margin="44,89,-44,-89"></TextBlock>

    </Canvas>
    <Button x:Name="button" Background="Gray" Content="Save" HorizontalAlignment="Left" VerticalAlignment="Top" Click="button_Click" />

i removed the button from canvas because you are using negative margin which is out of your canvas ant when you capture it or save it it renders dark black background so if you want button on it so place button inside the canvas

C#

private async void button_Click(object sender, RoutedEventArgs e)
{
    RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
    await renderTargetBitmap.RenderAsync(ImageHolder);

    var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
    var pixels = pixelBuffer.ToArray();
    var displayInformation = DisplayInformation.GetForCurrentView();
    var picker = new FileSavePicker();
    picker.FileTypeChoices.Add("JPEG Image", new string[] { ".jpg" });
    StorageFile file = await picker.PickSaveFileAsync();
    using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
        encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, displayInformation.RawDpiX, displayInformation.RawDpiY, pixels);
        await encoder.FlushAsync();
    }
}

FOR PNG (Bonus)

XAML --> Your regular above XAML

because you will always get transparent background irrespective of any margin

private async void button_Click(object sender, RoutedEventArgs e)
{
    RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
     await renderTargetBitmap.RenderAsync(ImageHolder);

     var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
     var pixels = pixelBuffer.ToArray();
     var displayInformation = DisplayInformation.GetForCurrentView();
     var picker = new FileSavePicker();
     picker.FileTypeChoices.Add("PNG Image", new string[] { ".png" });
     StorageFile file = await picker.PickSaveFileAsync();             
     using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
     {
         var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
         encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, displayInformation.RawDpiX, displayInformation.RawDpiY, pixels);
         await encoder.FlushAsync();
     }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM