(UWP) 将网格另存为 png [英] (UWP) Save Grid as png

查看:35
本文介绍了(UWP) 将网格另存为 png的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 UWP 应用程序,该应用程序具有一个包含子项、图像和文本块的网格.我有两件事想要实现并需要帮助.

  1. 如何将 Grid 元素及其子内容保存为具有预定义名称的本地文件夹中的图像(最好是 PNG)?

  2. 如何取回此保存的图像,然后将其作为附件与其他兼容应用共享?

示例:

 <网格名称="myGrid"水平对齐=拉伸"背景=黑色"><图像名称="myImage"来源="资产/image1.png"拉伸=统一"/><TextBlock 名称="myTextBlock"水平对齐=中心"垂直对齐=中心"TextWrapping="Wrap"文本="示例用户文本"/></网格><按钮名称="saveButton"内容="保存"保证金="10,10,0,0"Click="saveButton_Click"/><按钮名称="shareButton"内容="分享"保证金="10,10,0,0"Click="shareButton_Click"/></StackPanel>

在 saveButton_Click 事件中尝试了这段代码.似乎不起作用.

 RenderTargetBitmap rtb = new RenderTargetBitmap();等待 rtb.RenderAsync(myGrid);var pixelBuffer = 等待 rtb.GetPixelsAsync();var pixel = pixelBuffer.ToArray();var displayInformation = DisplayInformation.GetForCurrentView();var stream = new InMemoryRandomAccessStream();var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);编码器.SetPixelData(BitmapPixelFormat.Bgra8,BitmapAlphaMode.Premultiplied,(uint)rtb.PixelWidth,(uint)rtb.PixelHeight,displayInformation.RawDpiX,displayInformation.RawDpiY,像素);等待encoder.FlushAsync();流.寻求(0);FileStream filestream = File.Create("C:\\Users\\pcUser\\Desktop\\testimage.png", (int)stream.Size);

试过这段代码.它似乎有些工作,但我只得到一个黑色图像,这可能是因为它只保存 myGrid,而不是儿童的内容.

 RenderTargetBitmap rtb = new RenderTargetBitmap();等待 rtb.RenderAsync(quoteGrid);var pixelBuffer = 等待 rtb.GetPixelsAsync();var pixel = pixelBuffer.ToArray();var displayInformation = DisplayInformation.GetForCurrentView();var stream = new InMemoryRandomAccessStream();var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);编码器.SetPixelData(BitmapPixelFormat.Bgra8,BitmapAlphaMode.Premultiplied,(uint)rtb.PixelWidth,(uint)rtb.PixelHeight,displayInformation.RawDpiX,displayInformation.RawDpiY,像素);等待encoder.FlushAsync();流.寻求(0);var wbm = new WriteableBitmap(rtb.PixelWidth, rtb.PixelHeight);等待 wbm.SetSourceAsync(stream);StorageFolder 文件夹 = ApplicationData.Current.LocalFolder;如果(文件夹!= null){StorageFile file = await folder.CreateFileAsync("testImage" + ".png", CreationCollisionOption.ReplaceExisting);使用 (var storageStream = await file.OpenAsync(FileAccessMode.ReadWrite)){编码器 = 等待 BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, storageStream);var pixelStream = wbm.PixelBuffer.AsStream();等待 pixelStream.ReadAsync(pixels, 0, pixel.Length);编码器.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)wbm.PixelWidth, (uint)wbm.PixelHeight, displayInformation.RawDpiX, displayInformation.RawDpiY, new byte[pixelStream.Length]);等待encoder.FlushAsync();}}

解决方案

如何将 Grid 元素及其子内容保存为具有预定义名称的本地文件夹中的图像(最好是 PNG)?

我已经检查了你的代码.您不需要使用WriteableBitmap,只需将文件流传递给BitmapEncoder.CreateAsync 方法.详情请查看以下代码:

private async void saveButton_Click(object sender, RoutedEventArgs e){RenderTargetBitmap rtb = new RenderTargetBitmap();等待 rtb.RenderAsync(myGrid);var pixelBuffer = 等待 rtb.GetPixelsAsync();var pixel = pixelBuffer.ToArray();var displayInformation = DisplayInformation.GetForCurrentView();var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("testImage" + ".png", CreationCollisionOption.ReplaceExisting);使用 (var stream = await file.OpenAsync(FileAccessMode.ReadWrite)){var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);编码器.SetPixelData(BitmapPixelFormat.Bgra8,BitmapAlphaMode.Premultiplied,(uint)rtb.PixelWidth,(uint)rtb.PixelHeight,displayInformation.RawDpiX,displayInformation.RawDpiY,像素);等待encoder.FlushAsync();}}

<块引用>

如何取回此保存的图像,然后将其作为附件与其他兼容应用共享?

对于您的情况,您将图片保存在本地文件夹中.因此,如果您想获得它,则需要使用 Storage API.例如:

var file = await ApplicationData.Current.LocalFolder.GetFileAsync("testImage.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.

这篇关于(UWP) 将网格另存为 png的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆