2016-12-28 65 views
1

我正在開發一個UWP應用程序,該應用程序具有帶childs,Image和TextBlock的網格。我有兩件事情我想實現並需要幫助。(UWP)將網格另存爲PNG

  1. 如何使用預定義名稱將Grid元素及其子內容保存爲本地文件夾中的圖像(最好是PNG)?

  2. 我該如何檢索此保存的圖像,然後將其包含爲附件以與其他兼容應用程序共享?

實施例:

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

編輯2:試了這一點的代碼。這似乎有點工作,但我只得到一個黑色的圖像,這可能是因爲它只是保存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(); 
     } 
    } 
+0

看起來您可以使用Windows.UI.Xaml.Media.Imaging命名空間中的RenderTargetBitmap類執行第1步。本指南的第一部分很好地解決了這個問題:http://metulev.com/render-xaml- to-image-and-more/ –

+0

@LincolnGreen那麼我該如何保存RenderTargetBitmap對象?我對Windows編程非常陌生。 –

+0

只需將流保存到文件中 – chris579

回答

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

如何取回這個保存的圖像回來,然後包括它作爲附件與其他兼容的應用程序分享嗎?

對於您的情況,您將圖片保存在本地文件夾中。所以,如果你想要得到它,你將需要使用存儲APIs.For例如:

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

關於「包括其作爲附件與其他兼容的應用分享」,你可以參考官方Sharing content source app sample的細節。

+0

工程太棒了!非常感謝你! –