2009-02-26 131 views
7

我发布了几个与我遇到的问题有关的问题,我开始相信这是不能做到的。这是后面的故事。在WPF运行时渲染图像

我有一个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; 
} 

感谢您的帮助。

+1

我喜欢它,当我找到我的问题的答案,而不必问 - 感谢遇到同样的问题,并帮助我解决我的问题! – 2010-08-14 21:20:27

回答

14

您正在渲染输出位图,它只是您正在拍摄的输入位图:)。

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

+1

非常感谢!这完全解决了我的问题。我疯了。 – user70192 2009-02-26 13:30:36