Rendering WPF Visuals to Bitmap

Sometimes we need to convert a WPF Window or Control (or any other type of Visual) to a plain old GDI+ Bitmap. In WinForms, creating a Bitmap of a Window or Control is quite complex. In WPF it's a piece of cake, at least if you're comfortable with the citizens of the System.Windows.Media.Imaging namespace, like RenderTargetBitmap, and the range of BitmapEncoders. I created a little helper class with some extension methods to Visual to facilitate the process. The class comes with a PngBitmap method that returns a Bitmap (PNG format), and a BitmapSource method for data binding, e.g. to a WPF Image control.

This is a screenshot of a small sample. The textbox and ellipse in the upper part of the window are original WPF Controls. The lower part of the window is a bitmap of the upper part, displayed in an Image control:

The Window has the following XAML content:

            Text="Dock of the Bay" />
            Height="50" Width="50"
            Fill="DeepSkyBlue" Stroke="MidnightBlue"
            HorizontalAlignment="Left" />
            x:Name="ScreenShotImage" />

The screenshot is taken, and displayed in the Image control with the following one-liner:

   this.ScreenShotImage.Source = this.BitmapSource();

Here's the whole extension class:

// <copyright file="VisualExtensions.cs" company="DockOfTheBay">
// </copyright>
// <summary>Defines the VisualExtensions class.</summary>
namespace DockOfTheBay
    using System;
    using System.Drawing;           // Need reference to System.Drawing.dll
    using System.Windows;
    using System.Windows.Interop;   // Need reference to PresentationCore.dll
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    /// <summary>
    /// Extension Methods for the System.Windows.Media.Visual Class
    /// </summary>
    public static class VisualExtensions
        /// <summary>
        /// Returns the contents of a WPF Visual as a Bitmap in PNG format.
        /// </summary>
        /// <param name="visual">A WPF Visual.</param>
        /// <returns>A GDI+ System.Drawing.Bitmap.</returns>
        public static Bitmap PngBitmap(this Visual visual)
            // Get height and width
            int height = (int)(double)visual.GetValue(FrameworkElement.ActualWidthProperty);
            int width = (int)(double)visual.GetValue(FrameworkElement.ActualHeightProperty);
            // Render
            RenderTargetBitmap rtb =
                new RenderTargetBitmap(
            // Encode
            PngBitmapEncoder encoder = new PngBitmapEncoder();
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            // Create Bitmap
            Bitmap bmp = new Bitmap(stream);
            return bmp;
        /// <summary>
        /// Returns the contents of a WPF Visual as a BitmapSource, e.g.
        /// for binding to an Image control.
        /// </summary>
        /// <param name="visual">A WPF Visual.</param>
        /// <returns>A set of pixels.</returns>
        public static BitmapSource BitmapSource(this Visual visual)
            Bitmap bmp = visual.PngBitmap();
            IntPtr hBitmap = bmp.GetHbitmap();
            BitmapSizeOptions sizeOptions = BitmapSizeOptions.FromEmptyOptions();
            return Imaging.CreateBitmapSourceFromHBitmap(

By the way, if you prefer to screen capture to XPS instead of to a Bitmap, then I suggest this article.

1 comment:

  1. If you need your ex-girlfriend or ex-boyfriend to come crawling back to you on their knees (no matter why you broke up) you got to watch this video
    right away...

    (VIDEO) Text Your Ex Back?