【问题标题】:Save content of a visual Object as a image file in WPF?将可视对象的内容保存为 WPF 中的图像文件?
【发布时间】:2011-04-06 18:35:53
【问题描述】:

我需要将 WPF 对象的内容保存为图像文件。在我的应用程序中,我在 Canvas 对象上绘制了一个图表。这是我需要保存的。包含所有子对象的 Canvas。

【问题讨论】:

    标签: wpf image canvas


    【解决方案1】:

    您正在寻找的是RenderTargetBitmap 类。在我链接的 MSDN 页面上有一个使用示例,还有另一个很好的示例,包括在此处保存到文件:

    RenderTargetBitmap by Eric Sinc

    【讨论】:

      【解决方案2】:

      这里是创建RenderTargetBitmap 对象的函数,将在后续函数中使用。

      public static RenderTargetBitmap ConvertToBitmap(UIElement uiElement, double resolution)
      {
          var scale = resolution / 96d;
      
          uiElement.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
          var sz = uiElement.DesiredSize;
          var rect = new Rect(sz);
          uiElement.Arrange(rect);
      
          var bmp = new RenderTargetBitmap((int)(scale * (rect.Width)), (int)(scale * (rect.Height)), scale * 96, scale * 96, PixelFormats.Default);
          bmp.Render(uiElement);
      
          return bmp;
      }
      

      此函数创建文件的JPEG字符串内容并将其写入文件:

      public static void ConvertToJpeg(UIElement uiElement, string path, double resolution)
      {
          var jpegString = CreateJpeg(ConvertToBitmap(uiElement, resolution));
      
          if (path != null)
          {
              try
              {
                  using (var fileStream = File.Create(path))
                  {
                      using (var streamWriter = new StreamWriter(fileStream, Encoding.Default))
                      {
                          streamWriter.Write(jpegString);
                          streamWriter.Close();
                      }
      
                      fileStream.Close();
                  }
              }    
      
              catch (Exception ex)
              {
                  //TODO: handle exception here
              }
          }
       }
      

      上面使用此函数创建图像内容的 JPEG 字符串表示:

      public static string CreateJpeg(RenderTargetBitmap bitmap)
      {
          var jpeg = new JpegBitmapEncoder();
          jpeg.Frames.Add(BitmapFrame.Create(bitmap));
          string result;
      
          using (var memoryStream = new MemoryStream())
          {
              jpeg.Save(memoryStream);
              memoryStream.Seek(0, SeekOrigin.Begin);
      
              using (var streamReader = new StreamReader(memoryStream, Encoding.Default))
              {
                  result = streamReader.ReadToEnd();
                  streamReader.Close();
              }
      
              memoryStream.Close();
          }
      
          return result;
      }
      

      希望这会有所帮助。

      【讨论】:

      • 哦,请不要将二进制数据写入字符串。字符串用于字符,而不是字节。使用 Encoding.Default 会导致世界上其他计算机上出现不可预测的行为。它可能会破坏图像文件的数据结构。我们生活在一个 Unicode 的世界里,ASCII==bytes 的日子已经一去不复返了。如果有的话,为图像数据返回一个 MemoryStream 或一个 byte[] 数组。
      • 或者更确切地说,请注意 BitmapEncoder.Save 方法采用 Stream,因此它可以将数据直接转储到 FileStream 而不是所有那些复制
      【解决方案3】:

      在 Eric Sinc 教程的帮助下,我找到了以下解决方案: 它使用 win32 SaveDialog 来选择文件的存放位置,并使用 PngBitmapEncoder(许多其他 BitmapEncoders 可用!)将其转换为我们可以保存的内容。

      请注意,此示例中保存的元素是“cnvClasses”,并且输出的大小故意与控件相同。

              SaveFileDialog svDlg = new SaveFileDialog();
              svDlg.Filter = "PNG files|*.png|All Files|*.*";
              svDlg.Title = "Save diagram as PNG";
              if (svDlg.ShowDialog().Value == true)
              {
                  RenderTargetBitmap render = new RenderTargetBitmap((int)this.cnvClasses.ActualWidth, (int)this.cnvClasses.ActualHeight, 96, 96, PixelFormats.Pbgra32);
                  render.Render(cnvClasses);
                  PngBitmapEncoder encoder = new PngBitmapEncoder();
                  encoder.Frames.Add(BitmapFrame.Create(render));
                  using (FileStream fs = new FileStream(svDlg.FileName, FileMode.Create))
                      encoder.Save(fs);
              }
      

      【讨论】:

        猜你喜欢
        • 2018-03-01
        • 1970-01-01
        • 2021-10-12
        • 1970-01-01
        • 1970-01-01
        • 2014-09-16
        • 2012-07-10
        • 2015-11-02
        • 2017-01-28
        相关资源
        最近更新 更多