As part of a side project, I needed to take the contents of a WPF application render it (or a subset of it on a Canvas) as a bitmap.
The attached Visual Studio 2008 sample application shows how to accomplish both tasks.
To illustrate, this is the application window
Clicking Save Window will save the image the following image to “d:\window.png”
Clicking Save Canvas will save the image the following image to “d:\canvas.png”
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.Navigation; using System.Windows.Shapes; namespace WpfApplication1 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void button_save_window_Click(object sender, RoutedEventArgs e) { util.SaveWindow(this,96,"d:\\window.png"); } private void button_save_canvas_Click(object sender, RoutedEventArgs e) { util.SaveCanvas(this,this.canvas1, 96, "d:\\canvas.png"); } } public static class util { public static void SaveWindow(Window window, int dpi, string filename) { var rtb = new RenderTargetBitmap( (int)window.Width, //width (int)window.Width, //height dpi, //dpi x dpi, //dpi y PixelFormats.Pbgra32 // pixelformat ); rtb.Render(window); SaveRTBAsPNG(rtb, filename); } public static void SaveCanvas(Window window, Canvas canvas, int dpi, string filename) { Size size = new Size(window.Width , window.Height ); canvas.Measure(size); //canvas.Arrange(new Rect(size)); var rtb = new RenderTargetBitmap( (int)window.Width, //width (int)window.Height, //height dpi, //dpi x dpi, //dpi y PixelFormats.Pbgra32 // pixelformat ); rtb.Render(canvas); SaveRTBAsPNG(rtb, filename); } private static void SaveRTBAsPNG(RenderTargetBitmap bmp, string filename) { var enc = new System.Windows.Media.Imaging.PngBitmapEncoder(); enc.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bmp)); using (var stm = System.IO.File.Create(filename)) { enc.Save(stm); } } } }
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.Navigation; using System.Windows.Shapes;
namespace WpfApplication1 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); }
private void button_save_window_Click(object sender, RoutedEventArgs e) {
util.SaveWindow(this,96,"d:\\window.png"); }
private void button_save_canvas_Click(object sender, RoutedEventArgs e) {
util.SaveCanvas(this,this.canvas1, 96, "d:\\canvas.png"); } }
public static class util { public static void SaveWindow(Window window, int dpi, string filename) {
var rtb = new RenderTargetBitmap( (int)window.Width, //width (int)window.Width, //height dpi, //dpi x dpi, //dpi y PixelFormats.Pbgra32 // pixelformat ); rtb.Render(window);
SaveRTBAsPNG(rtb, filename);
}
public static void SaveCanvas(Window window, Canvas canvas, int dpi, string filename) { Size size = new Size(window.Width , window.Height ); canvas.Measure(size); //canvas.Arrange(new Rect(size));
var rtb = new RenderTargetBitmap( (int)window.Width, //width (int)window.Height, //height dpi, //dpi x dpi, //dpi y PixelFormats.Pbgra32 // pixelformat ); rtb.Render(canvas);
SaveRTBAsPNG(rtb, filename); }
private static void SaveRTBAsPNG(RenderTargetBitmap bmp, string filename) { var enc = new System.Windows.Media.Imaging.PngBitmapEncoder(); enc.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bmp));
using (var stm = System.IO.File.Create(filename)) { enc.Save(stm); } } } }
It resizes the Canvas element which is not what I wanted.
Soon I’ll post an example of how to save a WPF animation as an video file.