【问题标题】:Rendering an image at runtime in WPF在 WPF 中运行时渲染图像
【发布时间】:2009-02-26 05:00:51
【问题描述】:

我已经发布了几个与我遇到的这个问题相关的问题,我开始相信这是不可能的。这是背景故事。

我有一个 ASP.NET 应用程序,我想从中生成一个 .png 图像。此 .png 图像需要从 XAML 或 WPF 可视树构造。因此,我必须在 STA 线程中生成 .png 图像。一切正常,直到我的 XAML/WPF 可视树包含一个图像(如在 System.Windows.Controls.Image 中)。我的 .png 文件会正确生成,但 Image 元素不显示引用的图片。引用的图片位于远程 URL。不会抛出任何错误或异常。

如何从一些包含 System.Windows.Controls.Image 元素的 XAML/WPF 可视化树创建 .png 图像?生成的 .png 必须包含 Image 元素中引用的图片。我以多种方式尝试了以下代码:

string address = "http://imgtops.sourceforge.net/bakeoff/o-png24.png";

WebClient webClient = new WebClient();
byte[] imageContent = webClient.DownloadData(address);

Image image = new Image();
using (MemoryStream memoryStream = new MemoryStream(imageContent))
{
  BitmapImage imageSource = new BitmapImage();
  imageSource.BeginInit();
  imageSource.StreamSource = memoryStream;
  imageSource.EndInit();
  image.Source = imageSource;
}

// Set the size
image.Height = 200;
image.Width = 300;

// Position the Image within a Canvas
image.SetValue(Canvas.TopProperty, 1.0);
image.SetValue(Canvas.LeftProperty, 1.0);

Canvas canvas = new Canvas();
canvas.Height = 200;
canvas.Width = 300;
canvas.Background = new SolidColorBrush(Colors.Purple);
canvas.Children.Add(image);

// Create the area
Size availableSize = new Size(300, 200);
frameworkElement.Measure(availableSize);
frameworkElement.Arrange(new Rect(availableSize));

// Convert the WPF representation to a PNG file            
BitmapSource bitmap = RenderToBitmap(frameworkElement);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));

// Generate the .png
FileStream fileStream = new FileStream(filename, FileMode.Create);
encoder.Save(fileStream);


public BitmapSource RenderToBitmap(FrameworkElement target)
{
  int actualWidth = 300;
  int actualHeight = 200;

  Rect boundary = VisualTreeHelper.GetDescendantBounds(target);
  RenderTargetBitmap renderBitmap = new RenderTargetBitmap(actualWidth, actualHeight, 96, 96, PixelFormats.Pbgra32);

  DrawingVisual drawingVisual = new DrawingVisual();
  using (DrawingContext context = drawingVisual.RenderOpen())
  {
    VisualBrush visualBrush = new VisualBrush(target);
    context.DrawRectangle(visualBrush, null, new Rect(new Point(), boundary.Size));
  }

  renderBitmap.Render(drawingVisual);
  return renderBitmap;
}

感谢您的帮助。

【问题讨论】:

  • 我喜欢不用问就能找到问题的答案 - 感谢您遇到与我相同的问题并帮助我解决问题!

标签: c# wpf image


【解决方案1】:

您正在正确渲染输出位图,它只是您搞砸的输入位图:)。

BitmapImage 需要访问 StreamSource 属性,直到它触发 DownloadCompleted 事件,但是 MemoryStream 的“使用”块Dispose()s 在它有机会之前!您可以简单地从 using 块中解开 MemoryStream 并让 GC 处理它(如果这样做,我建议将 BitmapImage.CacheOption 设置为 BitmapCacheOption.None,因此它直接使用流,而不是副本),但我会使用 UriSource 属性并在渲染前等待 DownloadComplete 事件。

【讨论】:

  • 非常感谢!这完全解决了我的问题。我快疯了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 2014-02-03
  • 2014-09-11
相关资源
最近更新 更多