参考 wpf 对控件进行截图,获取快照 - 大海的泡沫 - 博客园
但该文中的情况是针对已经显示的控件,有另一种情况是,我控件或者弹窗是不显示的,只存在于内存中,这种情况下如果也需要生成该控件的截图可以使用如下方式:
- ///
- /// 不弹出控件的情况下,将控件内容生成截图
- ///
- /// 图片宽度
- /// 图片高度
- /// 目标控件
- /// 是否需要重新渲染:true(是),false(否)
- ///
- public static System.Drawing.Bitmap ToBitmap(this FrameworkElement visualToRender,
- Double width, Double height, Boolean undoTransformation)
- {
- try
- {
- #region 将目标控件放到 Viewbox中渲染
- visualToRender.Width = width;
- visualToRender.Height = height;
- visualToRender.RenderSize = new System.Windows.Size(width, height);
- var viewbox = new Viewbox();
- viewbox.Width = width;
- viewbox.Height = height;
- viewbox.Child = visualToRender;
- viewbox.Measure(visualToRender.RenderSize);
- viewbox.Arrange(new Rect(new System.Windows.Point(0, 0), visualToRender.RenderSize));
- viewbox.UpdateLayout();
- #endregion
-
- var bitSrc = CreateBitmapFromVisual(width, height, visualToRender, undoTransformation);
- var bit = bitSrc.BitmapSourceToBitmap();
- return bit;
- }
- catch { }
-
- return null;
- }
-
- private static BitmapSource CreateBitmapFromVisual(Double width,
- Double height,
- Visual visualToRender,
- Boolean undoTransformation)
- {
- if (visualToRender == null)
- {
- return null;
- }
-
- // The PixelsPerInch() helper method is used to read the screen DPI setting.
- // If you need to create a bitmap with a specified resolution, you could directly
- // pass the specified dpiX and dpiY values to RenderTargetBitmap constructor.
- RenderTargetBitmap bmp = new RenderTargetBitmap((Int32)Math.Ceiling(width),
- (Int32)Math.Ceiling(height),
- (Double)DeviceHelper.PixelsPerInch(Orientation.Horizontal),
- (Double)DeviceHelper.PixelsPerInch(Orientation.Vertical),
- PixelFormats.Pbgra32);
-
- // If we want to undo the transform, we could use VisualBrush trick.
- if (undoTransformation)
- {
- DrawingVisual dv = new DrawingVisual();
- using (DrawingContext dc = dv.RenderOpen())
- {
- VisualBrush vb = new VisualBrush(visualToRender);
- dc.DrawRectangle(vb, null, new Rect(new System.Windows.Point(), new System.Windows.Size(width, height)));
- }
- bmp.Render(dv);
- }
- else
- {
- bmp.Render(visualToRender);
- }
-
- return bmp;
- }
-
- ///
- /// BitmapSource转Bitmap
- ///
- ///
- ///
- public static System.Drawing.Bitmap BitmapSourceToBitmap(this BitmapSource source)
- {
- return BitmapSourceToBitmap(source, source.PixelWidth, source.PixelHeight);
- }
-
- ///
- /// Convert BitmapSource to Bitmap
- ///
- ///
- ///
- public static System.Drawing.Bitmap BitmapSourceToBitmap(this BitmapSource source, int width, int height)
- {
- System.Drawing.Bitmap bmp = null;
- try
- {
- System.Drawing.Imaging.PixelFormat format = System.Drawing.Imaging.PixelFormat.Format24bppRgb;
- /*set the translate type according to the in param(source)*/
- switch (source.Format.ToString())
- {
- case "Rgb24":
- case "Bgr24": format = System.Drawing.Imaging.PixelFormat.Format24bppRgb; break;
- case "Bgra32": format = System.Drawing.Imaging.PixelFormat.Format32bppPArgb; break;
- case "Bgr32": format = System.Drawing.Imaging.PixelFormat.Format32bppRgb; break;
- case "Pbgra32": format = System.Drawing.Imaging.PixelFormat.Format32bppArgb; break;
- }
- bmp = new Bitmap(width, height, format);
- BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size),
- ImageLockMode.WriteOnly,
- format);
- source.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
- bmp.UnlockBits(data);
- }
- catch
- {
- if (bmp != null)
- {
- bmp.Dispose();
- bmp = null;
- }
- }
-
- return bmp;
- }
- }
-
- internal class DeviceHelper
- {
- public static Int32 PixelsPerInch(Orientation orientation)
- {
- Int32 capIndex = (orientation == Orientation.Horizontal) ? 0x58 : 90;
- using (DCSafeHandle handle = UnsafeNativeMethods.CreateDC("DISPLAY"))
- {
- return (handle.IsInvalid ? 0x60 : UnsafeNativeMethods.GetDeviceCaps(handle, capIndex));
- }
- }
- }
-
- internal sealed class DCSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
- {
- private DCSafeHandle() : base(true) { }
-
- protected override Boolean ReleaseHandle()
- {
- return UnsafeNativeMethods.DeleteDC(base.handle);
- }
- }
-
- [SuppressUnmanagedCodeSecurity]
- internal static class UnsafeNativeMethods
- {
- [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
- public static extern Boolean DeleteDC(IntPtr hDC);
-
- [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
- public static extern Int32 GetDeviceCaps(DCSafeHandle hDC, Int32 nIndex);
-
- [DllImport("gdi32.dll", EntryPoint = "CreateDC", CharSet = CharSet.Auto)]
- public static extern DCSafeHandle IntCreateDC(String lpszDriver,
- String lpszDeviceName, String lpszOutput, IntPtr devMode);
-
- public static DCSafeHandle CreateDC(String lpszDriver)
- {
- return UnsafeNativeMethods.IntCreateDC(lpszDriver, null, null, IntPtr.Zero);
- }
- }