简体   繁体   中英

(UWP) Save Grid as png

I'm developing a UWP app that has a Grid with childs, Image and TextBlock. I have 2 things I would like to achieve and need help with.

  1. How do I save the Grid element along with it's child contents as an image(preferably PNG) in the local folder with a predefined name?

  2. How do I retrieve this saved image back and then include it as an attachment to share with other compatible apps?

Example:

    <StackPanel Orientation="Vertical">
        <Grid Name="myGrid"
              HorizontalAlignment="Stretch"
              Background="Black">

            <Image Name="myImage"
                   Source="Assets/image1.png"
                   Stretch="Uniform"/>

            <TextBlock Name="myTextBlock"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       TextWrapping="Wrap"
                       Text="Sample user text"/>
        </Grid>

        <Button Name="saveButton"
                Content="Save"
                Margin="10,10,0,0"
                Click="saveButton_Click" />

        <Button Name="shareButton"
                Content="Share"
                Margin="10,10,0,0"
                Click="shareButton_Click" />
    </StackPanel>

EDIT: Tried this bit of code inside the saveButton_Click event. Doesn't seem to work.

    RenderTargetBitmap rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(myGrid);

    var pixelBuffer = await rtb.GetPixelsAsync();
    var pixels = pixelBuffer.ToArray();

    var displayInformation = DisplayInformation.GetForCurrentView();

    var stream = new InMemoryRandomAccessStream();
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
    encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                         BitmapAlphaMode.Premultiplied,
                         (uint)rtb.PixelWidth,
                         (uint)rtb.PixelHeight,
                         displayInformation.RawDpiX,
                         displayInformation.RawDpiY,
                         pixels);

    await encoder.FlushAsync();
    stream.Seek(0);

    FileStream filestream = File.Create("C:\\Users\\pcUser\\Desktop\\testimage.png", (int)stream.Size);

EDIT2: Tried this bit of code. It seems to somewhat work but I'm only getting a black image which is probably because it's only saving myGrid, not it's children's content.

    RenderTargetBitmap rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(quoteGrid);

    var pixelBuffer = await rtb.GetPixelsAsync();
    var pixels = pixelBuffer.ToArray();

    var displayInformation = DisplayInformation.GetForCurrentView();

    var stream = new InMemoryRandomAccessStream();
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
    encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                         BitmapAlphaMode.Premultiplied,
                         (uint)rtb.PixelWidth,
                         (uint)rtb.PixelHeight,
                         displayInformation.RawDpiX,
                         displayInformation.RawDpiY,
                         pixels);

    await encoder.FlushAsync();
    stream.Seek(0);

    var wbm = new WriteableBitmap(rtb.PixelWidth, rtb.PixelHeight);
    await wbm.SetSourceAsync(stream);

    StorageFolder folder = ApplicationData.Current.LocalFolder;
    if (folder != null)
    {
        StorageFile file = await folder.CreateFileAsync("testImage" + ".png", CreationCollisionOption.ReplaceExisting);
        using (var storageStream = await file.OpenAsync(FileAccessMode.ReadWrite))
        {
            encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, storageStream);
            var pixelStream = wbm.PixelBuffer.AsStream();
            await pixelStream.ReadAsync(pixels, 0, pixels.Length);
            encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)wbm.PixelWidth, (uint)wbm.PixelHeight, displayInformation.RawDpiX, displayInformation.RawDpiY, new byte[pixelStream.Length]);
            await encoder.FlushAsync();
        }
    }

How do I save the Grid element along with it's child contents as an image(preferably PNG) in the local folder with a predefined name?

I'v checked your code. You didn't need to use WriteableBitmap , just pass the file stream to BitmapEncoder.CreateAsync method. Please check the following code for details:

private async void saveButton_Click(object sender, RoutedEventArgs e)
{
        RenderTargetBitmap rtb = new RenderTargetBitmap();
        await rtb.RenderAsync(myGrid);

        var pixelBuffer = await rtb.GetPixelsAsync();
        var pixels = pixelBuffer.ToArray();
        var displayInformation = DisplayInformation.GetForCurrentView();
        var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("testImage" + ".png", CreationCollisionOption.ReplaceExisting);
        using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
        {
            var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
            encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                                 BitmapAlphaMode.Premultiplied,
                                 (uint)rtb.PixelWidth,
                                 (uint)rtb.PixelHeight,
                                 displayInformation.RawDpiX,
                                 displayInformation.RawDpiY,
                                 pixels);
            await encoder.FlushAsync();
        }
}

How do I retrieve this saved image back and then include it as an attachment to share with other compatible apps?

For your case, you save picture in local folder. So if you want to get it, you would need to use Storage APIs.For example:

var file = await ApplicationData.Current.LocalFolder.GetFileAsync("testImage.png");

About "include it as an attachment to share with other compatible app", you can refer to the official Sharing content source app sample for details.

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