在WPF中运行时渲染图像

7

我已经发布了几个与此问题相关的问题,但我开始相信这是无法完成的。以下是背景。

我有一个ASP.NET应用程序,我想从中生成一个.png图像。这个.png图像需要从XAML或WPF可视树中构建。因此,我必须在STA线程中生成.png图像。一切都很好,直到我的XAML/WPF可视树包含一个图片(如System.Windows.Controls.Image)。我的.png文件被正确生成,但图片元素不显示引用的图片。引用的图片位于远程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;
}

感谢您的帮助。

1
我喜欢在不必询问的情况下找到问题的答案 - 感谢你遇到了我遇到的同样的问题,并帮助我解决了我的问题! - Chris Koenig
1个回答

15
您已正确地呈现了输出位图,只是您在弄乱输入位图:)。
BitmapImage需要访问StreamSource属性,直到触发DownloadCompleted事件,但是'using'块在它有机会之前Dispose()了MemoryStream! 您可以简单地从使用块中解包MemoryStream,并让GC处理它(如果这样做,我建议将BitmapImage.CacheOption设置为BitmapCacheOption.None,以便直接使用流,而不是副本),但我建议使用UriSource属性并等待DownloadComplete事件再进行呈现。

1
非常感谢!这完全解决了我的问题。我都要发疯了。 - user70192

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接