整理的C#屏幕截图,控件截图程序

时间:2022-02-16 08:53:15

代码基本从网上搜集而来,整理成以下文件: 
包括屏幕截图(和屏幕上看到的一致); 
以及控件截图(只要该控件在本窗口内显示完全且不被其他控件遮挡就可正确截图)

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows.Forms;
  9. namespace LC
  10. {
  11. class ScreenCapture
  12. {
  13. #region 抓取屏幕
  14. /// <summary>
  15. /// 抓取屏幕(层叠的窗口)
  16. /// </summary>
  17. /// <param name="x">左上角的横坐标</param>
  18. /// <param name="y">左上角的纵坐标</param>
  19. /// <param name="width">抓取宽度</param>
  20. /// <param name="height">抓取高度</param>
  21. /// <returns></returns>
  22. public static Bitmap captureScreen(int x, int y, int width, int height)
  23. {
  24. Bitmap bmp = new Bitmap(width, height);
  25. using (Graphics g = Graphics.FromImage(bmp))
  26. {
  27. g.CopyFromScreen(new Point(x, y), new Point(0, 0), bmp.Size);
  28. g.Dispose();
  29. }
  30. //bit.Save(@"capture2.png");
  31. return bmp;
  32. }
  33. /// <summary>
  34. ///  抓取整个屏幕
  35. /// </summary>
  36. /// <returns></returns>
  37. public static Bitmap captureScreen()
  38. {
  39. Size screenSize = Screen.PrimaryScreen.Bounds.Size;
  40. return captureScreen(0,0,screenSize.Width,screenSize.Height);
  41. }
  42. #endregion
  43. #region 使用BitBlt方法抓取控件,无论控件是否被遮挡
  44. /// <summary>
  45. /// 控件(窗口)的截图,控件被其他窗口(而非本窗口内控件)遮挡时也可以正确截图,使用BitBlt方法
  46. /// </summary>
  47. /// <param name="control">需要被截图的控件</param>
  48. /// <returns>该控件的截图,控件被遮挡时也可以正确截图</returns>
  49. public static Bitmap captureControl(Control control)
  50. {
  51. //调用API截屏
  52. IntPtr hSrce = GetWindowDC(control.Handle);
  53. IntPtr hDest = CreateCompatibleDC(hSrce);
  54. IntPtr hBmp = CreateCompatibleBitmap(hSrce, control.Width, control.Height);
  55. IntPtr hOldBmp = SelectObject(hDest, hBmp);
  56. if (BitBlt(hDest, 0, 0, control.Width, control.Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt))
  57. {
  58. Bitmap bmp = Image.FromHbitmap(hBmp);
  59. SelectObject(hDest, hOldBmp);
  60. DeleteObject(hBmp);
  61. DeleteDC(hDest);
  62. ReleaseDC(control.Handle, hSrce);
  63. // bmp.Save(@"a.png");
  64. // bmp.Dispose();
  65. return bmp;
  66. }
  67. return null;
  68. }
  69. //         /// <summary>
  70. //         /// 有问题!!!!!用户区域坐标不对啊
  71. //         /// 控件(窗口)的用户区域截图,控件被其他窗口(而非本窗口内控件)遮挡时也可以正确截图,使用BitBlt方法
  72. //         /// </summary>
  73. //         /// <param name="control">需要被截图的控件</param>
  74. //         /// <returns>控件(窗口)的用户区域截图</returns>
  75. //         public static Bitmap captureClientArea(Control control)
  76. //         {
  77. //
  78. //             Size sz = control.Size;
  79. //             Rectangle rect = control.ClientRectangle;
  80. //
  81. //
  82. //             //调用API截屏
  83. //             IntPtr hSrce = GetWindowDC(control.Handle);
  84. //             IntPtr hDest = CreateCompatibleDC(hSrce);
  85. //             IntPtr hBmp = CreateCompatibleBitmap(hSrce, rect.Width, rect.Height);
  86. //             IntPtr hOldBmp = SelectObject(hDest, hBmp);
  87. //             if (BitBlt(hDest, 0, 0, rect.Width, rect.Height, hSrce, rect.X, rect.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt))
  88. //             {
  89. //                 Bitmap bmp = Image.FromHbitmap(hBmp);
  90. //                 SelectObject(hDest, hOldBmp);
  91. //                 DeleteObject(hBmp);
  92. //                 DeleteDC(hDest);
  93. //                 ReleaseDC(control.Handle, hSrce);
  94. //                 // bmp.Save(@"a.png");
  95. //                 // bmp.Dispose();
  96. //                 return bmp;
  97. //             }
  98. //             return null;
  99. //
  100. //         }
  101. #endregion
  102. #region 使用PrintWindow方法抓取窗口,无论控件是否被遮挡
  103. /// <summary>
  104. /// 窗口的截图,窗口被遮挡时也可以正确截图,使用PrintWindow方法
  105. /// </summary>
  106. /// <param name="control">需要被截图的窗口</param>
  107. /// <returns>窗口的截图,控件被遮挡时也可以正确截图</returns>
  108. public static Bitmap captureWindowUsingPrintWindow(Form form)
  109. {
  110. return GetWindow(form.Handle);
  111. }
  112. private static Bitmap GetWindow(IntPtr hWnd)
  113. {
  114. IntPtr hscrdc = GetWindowDC(hWnd);
  115. Control control = Control.FromHandle(hWnd);
  116. IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, control.Width, control.Height);
  117. IntPtr hmemdc = CreateCompatibleDC(hscrdc);
  118. SelectObject(hmemdc, hbitmap);
  119. PrintWindow(hWnd, hmemdc, 0);
  120. Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
  121. DeleteDC(hscrdc);//删除用过的对象
  122. DeleteDC(hmemdc);//删除用过的对象
  123. return bmp;
  124. }
  125. #endregion
  126. #region  DLL calls
  127. [DllImport("gdi32.dll")]
  128. static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int
  129. wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop);
  130. [DllImport("gdi32.dll")]
  131. static extern IntPtr DeleteDC(IntPtr hDc);
  132. [DllImport("gdi32.dll")]
  133. static extern IntPtr DeleteObject(IntPtr hDc);
  134. [DllImport("gdi32.dll")]
  135. static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
  136. [DllImport("gdi32.dll")]
  137. static extern IntPtr CreateCompatibleDC(IntPtr hdc);
  138. [DllImport("gdi32.dll")]
  139. static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
  140. [DllImport("user32.dll")]
  141. public static extern IntPtr GetDesktopWindow();
  142. [DllImport("user32.dll")]
  143. public static extern IntPtr GetWindowDC(IntPtr ptr);
  144. [DllImport("user32.dll")]
  145. public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, UInt32 nFlags);
  146. [DllImport("user32.dll")]
  147. static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
  148. #endregion
  149. }
  150. }