(UWP)将网格另存为png

时间:2016-12-28 00:56:08

标签: c# uwp uwp-xaml

我正在开发一个UWP应用程序,其中包含带子项的Grid,Image和TextBlock。我有两件事我想要实现并需要帮助。

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

  2. 如何检索此已保存的图像,然后将其作为附件包含在与其他兼容应用共享中?

  3. 示例:

        <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>
    

    编辑:在saveButton_Click事件中尝试了这段代码。似乎不起作用。

        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:尝试了这段代码。它似乎有点工作,但我只是得到一个黑色的图像,这可能是因为它只是保存myGrid,而不是它的孩子的内容。

        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();
            }
        }
    

1 个答案:

答案 0 :(得分:0)

  

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

我检查了你的代码。您不需要使用WriteableBitmap,只需将文件流传递给BitmapEncoder.CreateAsync方法即可。请查看以下代码以获取详细信息:

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();
        }
}
  

如何检索此已保存的图像,然后将其作为附件包含在与其他兼容应用共享中?

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

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

关于&#34;将其作为附件与其他兼容应用进行分享&#34;,您可以参考官方Sharing content source app sample了解详情。