[WPF] From Visual to Bitmap

Posted by dariosantarelli on October 21, 2012

I’d like to share a couple of extension methods that helped me in situations where I needed to convert some rendered WPF windows or controls to bitmaps. Many devs know how complex this task was in Windows Forms. Instead, in WPF it’s quite simple, at least if you’re familiar with the RenderTargetBitmap class, and the range of BitmapEncoders. In order to convert a visual to a bitmap, I like to see something like this:


The ToBitmapSource() extension method allows you to get a single, constant set of pixels at a certain size and resolution representing the visual (please note that a BitmapSource uses automatic codec discovery, based on the installed codecs on the user’s system). I’ve always found useful to replace the default black background that WPF reserves for transparency with a custom brush. So I introduced the transparentBackground parameter (default: white) which overrides the default black one.

public static BitmapSource ToBitmapSource(this Visual visual, Brush transparentBackground)
  var bounds = VisualTreeHelper.GetDescendantBounds(visual);
  var bitmapSource = new RenderTargetBitmap((Int32)bounds.Width, (Int32)bounds.Height, 96, 96, PixelFormats.Pbgra32);
  var drawingVisual = new DrawingVisual(); 
  using (var drawingContext = drawingVisual.RenderOpen())
    var visualBrush = new VisualBrush(visual);
    drawingContext.DrawRectangle(transparentBackground, null, new Rect(new Point(), bounds.Size));
    drawingContext.DrawRectangle(visualBrush, null, new Rect(new Point(), bounds.Size));

  return bitmapSource;

public static BitmapSource ToBitmapSource(this Visual visual)
  return visual.ToBitmapSource(Brushes.White);

public static void ToPngFile(this BitmapSource bitmapSource, string fileName)
  var encoder = new PngBitmapEncoder();
  using (var file = File.Create(fileName)) encoder.Save(file);


One Response to “[WPF] From Visual to Bitmap”

  1. tpartee said

    Excellent post, thank you for sharing this code. I was having a problem converting a VisualBrush to a BitmapSource as the prescribed way to do that from MSDN results in a RenderTargetBitmap that does not appear on first render and being in a ListView I couldn’t force a re-render. I also couldn’t follow Jaime Rodriguez’ advice in placing the Image object inside a non-Margin container to get it to render correctly. So instead I used your extension method here with a Border that renders the VisualBrush as it’s Background contained in a Hidden StackPanel, then used the extension method here to turn it into the desired BitmapSource. Works like a charm, thanks again!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: