In previous discussion, we have covered the following topics
Convert from System.Drawing.Icon to System.Media.ImageSource and vice versa
wpf - how to create and save any visual element into a file
wpf Save a image using DrawingImage() and workaround the WebBrowser drawing issue
wpf - Draw Windows Forms Controls
c# - Convert from System.Drawing.Image to System.WIndows.Media.ImageSource
This topic is adding more routines/examples to the GDI drawing, control and Image conversions; This topic is more about converting some controls (wpf/silverlight/winforms) to Bitmap (or sources to Bitmap)
the original post is located here:
How to convert a UI Control in WPF/Silverlight/WinForms into a Bitmap;
ometimes you just need to convert a FrameworkElement/Control into a bitmap even though the control doesn't necessarily exist in the UI Tree. Usually people find themselves in this situation because the 2D Graphics Drawing library for WPF/Silverlight is completely non-existent and you just need a cheap way to draw a circle or text.
WPF
If the element was created programmatically and doesn't exist in the UI tree, you need to force it to update its layout using Measure/Arrange.
// using System, System.Windows, System.Windows.Media, System.Windows.Media.Imaging public BitmapSource CreateBitmap(FrameworkElement element, bool isInUiTree) { if (!isInUiTree) { element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); element.Arrange(new Rect(new Point(0, 0), frameworkElement.DesiredSize)); } int width = (int)Math.Ceiling(element.ActualWidth); int height = (int)Math.Ceiling(element.ActualHeight); width = width == 0 ? 1 : width; height = height == 0 ? 1 : height; RenderTargetBitmap rtbmp = new RenderTargetBitmap( width, height, 96, 96, PixelFormats.Default); rtbmp.Render(element); return rtbmp; }
The Render method of RenderTargetBitmap can take in any Visual, not just a FrameworkElement. Measure and Arrange exist on the UIElement class but the ActualWidth and ActualHeight properties only exist on FrameworkElement, so you need to know what the bounds are if it's a UIElement. If it's just a visual, then you there is no Measure or Arrange. It must already be in the UI Tree in order for it to work.
Silverlight
Silverlight is a bit easier. All you have to do is simply pass the UIElement into one of the constructors of WriteableBitmap. No Measure/Arrange silliness.
// using System, System.Windows, System.Windows.Media.Imaging public BitmapSource CreateBitmap(FrameworkElement element) { int width = (int)Math.Ceiling(element.ActualWidth); int height = (int)Math.Ceiling(element.ActualHeight); width = width == 0 ? 1 : width; height = height == 0 ? 1 : height; return new WriteableBitmap(element, null); }
WinForms
Why are you still using WinForms? Anyways...
// using System, System.Drawing, System.Windows.Forms, public Bitmap CreateBitmap(Control winformsControl) { int width = (int)Math.Ceiling(winformsControl.Width); int height = (int)Math.Ceiling(winformsControl.Height); width = width == 0 ? 1 : width; height = height == 0 ? 1 : height; Bitmap bmp = new Bitmap(width, height); winformsControls.DrawToBitmap(bmp, new Rectangle(0, 0, width, height)); return bmp; }