C# 非顶端窗口截图

2022-05-22 14:01:02

panel上可以通过DrawToBitmap截图,不管是否在屏幕外是否有遮挡

Bitmap sourceBitmap = new Bitmap(400, 300);
 //Control ct = frmMain.mianForm.panel1 as Control;

 //ct.DrawToBitmap(sourceBitmap, new System.Drawing.Rectangle(0, 0, 400, 300));
 panel1.DrawToBitmap(sourceBitmap, new System.Drawing.Rectangle(0, 0, 400, 300));
 sourceBitmap.Save(@"e:\123form2.bmp");

在图片上打水印

string strpath = @"e:\1.bmp";
 Bitmap bmp = new Bitmap(strpath);
 Graphics graphics = Graphics.FromImage(bmp);

 System.Drawing.SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Red);
 graphics.FillEllipse(myBrush, new System.Drawing.Rectangle(150, 200, 10, 10));//画圆

 try
 {
 bmp.Save(@"e:\new.bmp");
 }
 catch (Exception ex)
 {
 MessageBox.Show(ex.Message);
 }

抓屏截图
 Image objImage = new Bitmap(400, 300);
 Graphics g = Graphics.FromImage(objImage);
 g.CopyFromScreen(new System.Drawing.Point(Cursor.Position.X - 150, Cursor.Position.Y - 25), new System.Drawing.Point(0, 0), new Size(400, 300));
 IntPtr dc1 = g.GetHdc();
 g.ReleaseHdc(dc1);

 objImage.Save("e:\\test.jpg");

非顶端窗口截图

用Windows热键截图然后保存的我就不说了,地球人都知道.

如何截取非前端窗体的截图,要先获取所要截图的窗口的句柄IntPtr PicWindow = this.Handle

首先说一下PrintWindow这个API的使用

 public static Bitmap GetWindowCapture(IntPtr hWnd)
 {
 IntPtr hscrdc = GetWindowDC(hWnd);
 RECT windowRect = new RECT();
 GetWindowRect(hWnd, ref windowRect);
 int width = windowRect.right - windowRect.left;
 int height = windowRect.bottom - windowRect.top;

 IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, width, height);
 IntPtr hmemdc = CreateCompatibleDC(hscrdc);
 SelectObject(hmemdc, hbitmap);
 PrintWindow(hWnd, hmemdc, 0);
 Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
 DeleteDC(hscrdc);//删除用过的对象
 DeleteDC(hmemdc);//删除用过的对象
 return bmp;
 }

 [DllImport("user32.dll")]
 public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);

 [DllImport("gdi32.dll")]
 public static extern IntPtr CreateDC(
 string lpszDriver, // driver name驱动名
 string lpszDevice, // device name设备名
 string lpszOutput, // not used; should be NULL
 IntPtr lpInitData // optional printer data
 );
 [DllImport("gdi32.dll")]
 public static extern int BitBlt(
 IntPtr hdcDest, // handle to destination DC目标设备的句柄
 int nXDest, // x-coord of destination upper-left corner目标对象的左上角的X坐标
 int nYDest, // y-coord of destination upper-left corner目标对象的左上角的Y坐标
 int nWidth, // width of destination rectangle目标对象的矩形宽度
 int nHeight, // height of destination rectangle目标对象的矩形长度
 IntPtr hdcSrc, // handle to source DC源设备的句柄
 int nXSrc, // x-coordinate of source upper-left corner源对象的左上角的X坐标
 int nYSrc, // y-coordinate of source upper-left corner源对象的左上角的Y坐标
 UInt32 dwRop // raster operation code光栅的操作值
 );

 [DllImport("gdi32.dll")]
 public static extern IntPtr CreateCompatibleDC(
 IntPtr hdc // handle to DC
 );

 [DllImport("gdi32.dll")]
 public static extern IntPtr CreateCompatibleBitmap(
 IntPtr hdc, // handle to DC
 int nWidth, // width of bitmap, in pixels
 int nHeight // height of bitmap, in pixels
 );

 [DllImport("gdi32.dll")]
 public static extern IntPtr SelectObject(
 IntPtr hdc, // handle to DC
 IntPtr hgdiobj // handle to object
 );

 [DllImport("gdi32.dll")]
 public static extern int DeleteDC(
 IntPtr hdc // handle to DC
 );

 [DllImport("user32.dll")]
 public static extern bool PrintWindow(
 IntPtr hwnd, // Window to copy,Handle to the window that will be copied.
 IntPtr hdcBlt, // HDC to print into,Handle to the device context.
 UInt32 nFlags // Optional flags,Specifies the drawing options. It can be one of the following values.
 );

 [DllImport("user32.dll")]
 public static extern IntPtr GetWindowDC(
 IntPtr hwnd
 );

很遗憾,上面的确可以截取非前端窗体的截图,但是非GDI的程序是无法截图的比如DirectX

下面说一下BitBlt这个API的使用

 /// <summary>
 /// 提供全屏和指定窗口的截图 以及保存为文件的类
 /// </summary>
 public class ScreenCapture
 {
 /// <summary>
 /// 全屏截图
 /// </summary>
 /// <returns></returns>
 public Image CaptureScreen()
 {
 return CaptureWindow(User32.GetDesktopWindow());
 }
 /// <summary>
 /// 指定窗口截图
 /// </summary>
 /// <param name="handle">窗口句柄. (在windows应用程序中, 从Handle属性获得)</param>
 /// <returns></returns>
 public Image CaptureWindow(IntPtr handle)
 {
 IntPtr hdcSrc = User32.GetWindowDC(handle);
 User32.RECT windowRect = new User32.RECT();
 User32.GetWindowRect(handle, ref windowRect);
 int width = windowRect.right - windowRect.left;
 int height = windowRect.bottom - windowRect.top;
 IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
 IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
 IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
 GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
 GDI32.SelectObject(hdcDest, hOld);
 GDI32.DeleteDC(hdcDest);
 User32.ReleaseDC(handle, hdcSrc);
 Image img = Image.FromHbitmap(hBitmap);
 GDI32.DeleteObject(hBitmap);
 return img;
 }
 /// <summary>
 /// 指定窗口截图 保存为图片文件
 /// </summary>
 /// <param name="handle"></param>
 /// <param name="filename"></param>
 /// <param name="format"></param>
 public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
 {
 Image img = CaptureWindow(handle);
 img.Save(filename, format);
 }
 /// <summary>
 /// 全屏截图 保存为文件
 /// </summary>
 /// <param name="filename"></param>
 /// <param name="format"></param>
 public void CaptureScreenToFile(string filename, ImageFormat format)
 {
 Image img = CaptureScreen();
 img.Save(filename, format);
 }

 /// <summary>
 /// 辅助类 定义 Gdi32 API 函数
 /// </summary>
 private class GDI32
 {

 public const int SRCCOPY = 0x00CC0020;
 [DllImport("gdi32.dll")]
 public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
 int nWidth, int nHeight, IntPtr hObjectSource,
 int nXSrc, int nYSrc, int dwRop);
 [DllImport("gdi32.dll")]
 public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
 int nHeight);
 [DllImport("gdi32.dll")]
 public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
 [DllImport("gdi32.dll")]
 public static extern bool DeleteDC(IntPtr hDC);
 [DllImport("gdi32.dll")]
 public static extern bool DeleteObject(IntPtr hObject);
 [DllImport("gdi32.dll")]
 public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
 }

 /// <summary>
 /// 辅助类 定义User32 API函数
 /// </summary>
 private class User32
 {
 [StructLayout(LayoutKind.Sequential)]
 public struct RECT
 {
 public int left;
 public int top;
 public int right;
 public int bottom;
 }
 [DllImport("user32.dll")]
 public static extern IntPtr GetDesktopWindow();
 [DllImport("user32.dll")]
 public static extern IntPtr GetWindowDC(IntPtr hWnd);
 [DllImport("user32.dll")]
 public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
 [DllImport("user32.dll")]
 public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
 }
 }

上面的类 使用了BitBlt这个API 可以截取GDI或者非GDI图形 只不过,非前端窗体图形不能截获...

下面说一下不使用API 最简单的全屏截图方案

 public static Bitmap CopyPrimaryScreen()
 {
 Screen s = Screen.PrimaryScreen;
 Rectangle r = s.Bounds;
 int w = r.Width;
 int h = r.Height;
 Bitmap bmp = new Bitmap(w, h);
 Graphics g = Graphics.FromImage(bmp);
 g.CopyFromScreen
 (
 new Point(0, 0),
 new Point(0, 0),
 new Size(w, h)
 );
 return bmp;
 }

最后,试试下面这个办法:

只要窗体的visable为true,即使它在屏幕的外面也可以抓到图。如果为false,就是一张黑图了,赫赫。

public static Bitmap GetWindow(IntPtr hWnd)
 {
 IntPtr hscrdc = GetWindowDC(hWnd);
 Control control = Control.FromHandle(hWnd);
 IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, control.Width, control.Height);
 IntPtr hmemdc = CreateCompatibleDC(hscrdc);
 SelectObject(hmemdc, hbitmap);
 PrintWindow(hWnd, hmemdc, 0);
 Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
 DeleteDC(hscrdc);//删除用过的对象
 DeleteDC(hmemdc);//删除用过的对象
 return bmp;
 }

API声明

[DllImport("gdi32.dll")]
 public static extern IntPtr CreateDC(
 string lpszDriver, // driver name驱动名
 string lpszDevice, // device name设备名
 string lpszOutput, // not used; should be NULL
 IntPtr lpInitData // optional printer data
 );
 [DllImport("gdi32.dll")]
 public static extern int BitBlt(
 IntPtr hdcDest, // handle to destination DC目标设备的句柄
 int nXDest, // x-coord of destination upper-left corner目标对象的左上角的X坐标
 int nYDest, // y-coord of destination upper-left corner目标对象的左上角的Y坐标
 int nWidth, // width of destination rectangle目标对象的矩形宽度
 int nHeight, // height of destination rectangle目标对象的矩形长度
 IntPtr hdcSrc, // handle to source DC源设备的句柄
 int nXSrc, // x-coordinate of source upper-left corner源对象的左上角的X坐标
 int nYSrc, // y-coordinate of source upper-left corner源对象的左上角的Y坐标
 UInt32 dwRop // raster operation code光栅的操作值
 );

 [DllImport("gdi32.dll")]
 public static extern IntPtr CreateCompatibleDC(
 IntPtr hdc // handle to DC
 );

 [DllImport("gdi32.dll")]
 public static extern IntPtr CreateCompatibleBitmap(
 IntPtr hdc, // handle to DC
 int nWidth, // width of bitmap, in pixels
 int nHeight // height of bitmap, in pixels
 );

 [DllImport("gdi32.dll")]
 public static extern IntPtr SelectObject(
 IntPtr hdc, // handle to DC
 IntPtr hgdiobj // handle to object
 );

 [DllImport("gdi32.dll")]
 public static extern int DeleteDC(
 IntPtr hdc // handle to DC
 );

 [DllImport("user32.dll")]
 public static extern bool PrintWindow(
 IntPtr hwnd, // Window to copy,Handle to the window that will be copied.
 IntPtr hdcBlt, // HDC to print into,Handle to the device context.
 UInt32 nFlags // Optional flags,Specifies the drawing options. It can be one of the following values.
 );

 [DllImport("user32.dll")]
 public static extern IntPtr GetWindowDC(
 IntPtr hwnd
 );

  • 作者:webajax
  • 原文链接:https://blog.csdn.net/webajax/article/details/50360397
    更新时间:2022-05-22 14:01:02