WPF has a class that is called System.Windows.Media.DrawingVisual where you can pass a System.Windows.Controls.Visual to it and it is supposed draw/render the visual as it is on the screen to some place in the memory.
generaly you can have the following code to create a drawing visual .
public static DrawingVisual CreateDrawingVisual(FrameworkElement visual, double width, double height)
{
var drawingVisual = new DrawingVisual();
// open the Render of the DrawingVisual
using (var dc = drawingVisual.RenderOpen())
{
var vb = new VisualBrush(visual) { Stretch = Stretch.None };
var rectangle = new Rect
{
X = 0,
Y = 0,
Width = width,
Height = height,
};
// draw the white background
dc.DrawRectangle(Brushes.White, null, rectangle);
// draw the visual
dc.DrawRectangle(vb, null, rectangle);
}
return drawingVisual;
}
With the code above, you are create a drawing visual with the same size as the size of the element that you passed in. Also, it create some background for the drawing visual.
This all works well except that it does not work for the type WebBrowser. It does not fail, but you won't see anything if try to display the drawing visual.
There is a post on the web telling that "Save as Image using DrawingImage() in WPF". Basically the code that the author proposed is like this;
/*
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.IO;
*/
// Creates thumbnail image form the webbrowser control in wpf
// Or Thumbnail of web pages image created can be easily loaded in any
// image control..
public static string GetThumbnailImage(WebBrowser CurrentBrowser)
{
Guid guid = Guid.NewGuid();
string ThumbnailPath = @"E:\" + guid.ToString() + ".png";
Image imgScreen = new Image();
imgScreen.Width = 120;
imgScreen.Height = 100;
imgScreen.Source = new DrawingImage(VisualTreeHelper.GetDrawing(CurrentBrowser));
FileStream stream = new FileStream(ThumbnailPath, FileMode.Create);
DrawingVisual vis = new DrawingVisual();
DrawingContext cont = vis.RenderOpen();
cont.DrawImage(imgScreen.Source, new Rect(new Size(120d, 100d)));
cont.Close();
RenderTargetBitmap rtb = new RenderTargetBitmap((int)imgScreen.Width,
(int)imgScreen.Height, 96d, 96d, PixelFormats.Default);
rtb.Render(vis);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
encoder.Save(stream);
stream.Close();
return ThumbnailPath;
}
While If you adop the code above and you will probably do the following
public static DrawingVisual CreateDrawingImage(Visual visual, double width, double height)
{
var drawingVisual = new DrawingVisual();
// open the Render of the DrawingVisual
using (var dc = drawingVisual.RenderOpen())
{
var drawingImage = new DrawingImage(VisualTreeHelper.GetDrawing(visual));
var rectangle = new Rect
{
X = 0,
Y = 0,
Width = width,
Height = height,
};
// draw the white background
dc.DrawRectangle(Brushes.White, null, rectangle);
// draw the visual
//NOTE:
// instead of Creating one VisualBrush, it create and use one DrawingImage
// and use that DrawingImage , because VisualBrush has issue with WebBrowser
//
dc.DrawImage(drawingImage, rectangle);
}
return drawingVisual;
}
本文介绍如何使用WPF中的DrawingVisual类来创建视觉元素,并特别关注解决WebBrowser控件无法正常渲染的问题。通过使用DrawingImage替代VisualBrush,实现了WebBrowser内容的有效捕获。

被折叠的 条评论
为什么被折叠?



