• WPF不弹出控件的情况下,将控件内容生成截图


    参考 wpf 对控件进行截图,获取快照 - 大海的泡沫 - 博客园

    但该文中的情况是针对已经显示的控件,有另一种情况是,我控件或者弹窗是不显示的,只存在于内存中,这种情况下如果也需要生成该控件的截图可以使用如下方式:

    1. ///
    2. /// 不弹出控件的情况下,将控件内容生成截图
    3. ///
    4. /// 图片宽度
    5. /// 图片高度
    6. /// 目标控件
    7. /// 是否需要重新渲染:true(是),false(否)
    8. ///
    9. public static System.Drawing.Bitmap ToBitmap(this FrameworkElement visualToRender,
    10. Double width, Double height, Boolean undoTransformation)
    11. {
    12. try
    13. {
    14. #region 将目标控件放到 Viewbox中渲染
    15. visualToRender.Width = width;
    16. visualToRender.Height = height;
    17. visualToRender.RenderSize = new System.Windows.Size(width, height);
    18. var viewbox = new Viewbox();
    19. viewbox.Width = width;
    20. viewbox.Height = height;
    21. viewbox.Child = visualToRender;
    22. viewbox.Measure(visualToRender.RenderSize);
    23. viewbox.Arrange(new Rect(new System.Windows.Point(0, 0), visualToRender.RenderSize));
    24. viewbox.UpdateLayout();
    25. #endregion
    26. var bitSrc = CreateBitmapFromVisual(width, height, visualToRender, undoTransformation);
    27. var bit = bitSrc.BitmapSourceToBitmap();
    28. return bit;
    29. }
    30. catch { }
    31. return null;
    32. }
    33. private static BitmapSource CreateBitmapFromVisual(Double width,
    34. Double height,
    35. Visual visualToRender,
    36. Boolean undoTransformation)
    37. {
    38. if (visualToRender == null)
    39. {
    40. return null;
    41. }
    42. // The PixelsPerInch() helper method is used to read the screen DPI setting.
    43. // If you need to create a bitmap with a specified resolution, you could directly
    44. // pass the specified dpiX and dpiY values to RenderTargetBitmap constructor.
    45. RenderTargetBitmap bmp = new RenderTargetBitmap((Int32)Math.Ceiling(width),
    46. (Int32)Math.Ceiling(height),
    47. (Double)DeviceHelper.PixelsPerInch(Orientation.Horizontal),
    48. (Double)DeviceHelper.PixelsPerInch(Orientation.Vertical),
    49. PixelFormats.Pbgra32);
    50. // If we want to undo the transform, we could use VisualBrush trick.
    51. if (undoTransformation)
    52. {
    53. DrawingVisual dv = new DrawingVisual();
    54. using (DrawingContext dc = dv.RenderOpen())
    55. {
    56. VisualBrush vb = new VisualBrush(visualToRender);
    57. dc.DrawRectangle(vb, null, new Rect(new System.Windows.Point(), new System.Windows.Size(width, height)));
    58. }
    59. bmp.Render(dv);
    60. }
    61. else
    62. {
    63. bmp.Render(visualToRender);
    64. }
    65. return bmp;
    66. }
    67. ///
    68. /// BitmapSource转Bitmap
    69. ///
    70. ///
    71. ///
    72. public static System.Drawing.Bitmap BitmapSourceToBitmap(this BitmapSource source)
    73. {
    74. return BitmapSourceToBitmap(source, source.PixelWidth, source.PixelHeight);
    75. }
    76. ///
    77. /// Convert BitmapSource to Bitmap
    78. ///
    79. ///
    80. ///
    81. public static System.Drawing.Bitmap BitmapSourceToBitmap(this BitmapSource source, int width, int height)
    82. {
    83. System.Drawing.Bitmap bmp = null;
    84. try
    85. {
    86. System.Drawing.Imaging.PixelFormat format = System.Drawing.Imaging.PixelFormat.Format24bppRgb;
    87. /*set the translate type according to the in param(source)*/
    88. switch (source.Format.ToString())
    89. {
    90. case "Rgb24":
    91. case "Bgr24": format = System.Drawing.Imaging.PixelFormat.Format24bppRgb; break;
    92. case "Bgra32": format = System.Drawing.Imaging.PixelFormat.Format32bppPArgb; break;
    93. case "Bgr32": format = System.Drawing.Imaging.PixelFormat.Format32bppRgb; break;
    94. case "Pbgra32": format = System.Drawing.Imaging.PixelFormat.Format32bppArgb; break;
    95. }
    96. bmp = new Bitmap(width, height, format);
    97. BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size),
    98. ImageLockMode.WriteOnly,
    99. format);
    100. source.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
    101. bmp.UnlockBits(data);
    102. }
    103. catch
    104. {
    105. if (bmp != null)
    106. {
    107. bmp.Dispose();
    108. bmp = null;
    109. }
    110. }
    111. return bmp;
    112. }
    113. }
    114. internal class DeviceHelper
    115. {
    116. public static Int32 PixelsPerInch(Orientation orientation)
    117. {
    118. Int32 capIndex = (orientation == Orientation.Horizontal) ? 0x58 : 90;
    119. using (DCSafeHandle handle = UnsafeNativeMethods.CreateDC("DISPLAY"))
    120. {
    121. return (handle.IsInvalid ? 0x60 : UnsafeNativeMethods.GetDeviceCaps(handle, capIndex));
    122. }
    123. }
    124. }
    125. internal sealed class DCSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
    126. {
    127. private DCSafeHandle() : base(true) { }
    128. protected override Boolean ReleaseHandle()
    129. {
    130. return UnsafeNativeMethods.DeleteDC(base.handle);
    131. }
    132. }
    133. [SuppressUnmanagedCodeSecurity]
    134. internal static class UnsafeNativeMethods
    135. {
    136. [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    137. public static extern Boolean DeleteDC(IntPtr hDC);
    138. [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    139. public static extern Int32 GetDeviceCaps(DCSafeHandle hDC, Int32 nIndex);
    140. [DllImport("gdi32.dll", EntryPoint = "CreateDC", CharSet = CharSet.Auto)]
    141. public static extern DCSafeHandle IntCreateDC(String lpszDriver,
    142. String lpszDeviceName, String lpszOutput, IntPtr devMode);
    143. public static DCSafeHandle CreateDC(String lpszDriver)
    144. {
    145. return UnsafeNativeMethods.IntCreateDC(lpszDriver, null, null, IntPtr.Zero);
    146. }
    147. }

  • 相关阅读:
    SpringMVC(3)——REST风格
    Linux常用命令笔记
    MySQL GROUP BY和HAVING的使用 2022/09/09
    进入网络安全行业有哪些大公司推荐
    2678. 老人的数目 --力扣 --JAVA
    一个可见又不可见的窗口
    [HCTF 2018]admin
    Maven仓库地址(寻找Maven依赖)
    四传送皮带plc梯形图
    私有化部署的知识管理平台对企业有什么意义?
  • 原文地址:https://blog.csdn.net/fengxing666/article/details/128130221