2009-02-26 29 views
7

Tôi đã đăng một số câu hỏi liên quan đến vấn đề này mà tôi đang gặp phải và tôi bắt đầu tin rằng điều này không thể thực hiện được. Đây là câu chuyện sau.Dựng hình ảnh tại thời điểm chạy trong WPF

Tôi có một ứng dụng ASP.NET mà từ đó tôi muốn tạo một hình ảnh .png. Hình ảnh .png này cần phải được xây dựng từ XAML hoặc một cây trực quan WPF. Bởi vì điều này, tôi phải tạo ra hình ảnh .png trong một chuỗi STA. Tất cả mọi thứ hoạt động tốt cho đến khi XAML/WPF Visual Tree của tôi bao gồm một hình ảnh (như trong một System.Windows.Controls.Image). Tệp .png của tôi được tạo chính xác trừ phần tử Hình ảnh không hiển thị hình ảnh được tham chiếu. Ảnh được tham chiếu được đặt tại một URL từ xa. Không có lỗi hoặc ngoại lệ được ném.

Làm cách nào để tạo hình ảnh .png từ một số cây hình ảnh XAML/WPF bao gồm phần tử System.Windows.Controls.Image? Kết quả .png phải bao gồm hình ảnh được tham chiếu trong phần tử Hình ảnh. Tôi đã thử mã sau đây theo nhiều cách khác nhau:

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ảm ơn sự giúp đỡ của bạn.

+1

Tôi thích khi tôi tìm câu trả lời cho câu hỏi của mình mà không cần phải hỏi - cảm ơn vì đã chạy vào cùng một câu hỏi mà tôi có và giúp tôi làm việc thông qua các vấn đề của mình! –

Trả lời

14

Bạn đang hiển thị bitmap đầu ra chính xác, nó chỉ là bitmap đầu vào bạn đang xoay lên :).

BitmapImage yêu cầu quyền truy cập vào thuộc tính StreamSource cho đến khi nó kích hoạt sự kiện DownloadCompleted, nhưng 'sử dụng' chặn Dispose() s của MemoryStream trước khi có cơ hội! Bạn có thể đơn giản unwrap MemoryStream từ khối sử dụng và để cho GC xử lý nó (nếu bạn làm thế, tôi khuyên bạn nên thiết lập BitmapImage.CacheOption thành BitmapCacheOption.None, vì vậy nó sử dụng luồng trực tiếp, chứ không phải là bản sao), nhưng tôi sẽ sử dụng thuộc tính UriSource và đợi sự kiện DownloadComplete trước khi kết xuất.

+1

Cảm ơn bạn rất nhiều! Điều này hoàn toàn giải quyết được vấn đề của tôi. Tôi đã đi hạt. – user70192

+0

hoàn hảo! cảm ơn vì đã cung cấp câu trả lời này! –

Các vấn đề liên quan