DarioSantarelli.Blog(this);

Archive for October, 2012

[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:

myVisual.ToBitmapSource().ToPngFile(@”C:\ScreenShot.png”);

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));
  }

  bitmapSource.Render(drawingVisual);
  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();
  encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
  using (var file = File.Create(fileName)) encoder.Save(file);
}

Advertisements

Posted in .NET Framework, C#, Microsoft Technology, WPF | Tagged: , | 1 Comment »