2009-02-26 132 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