C# 非顶端窗口截图

来源:互联网 发布:婴儿面膜淘宝授权书 编辑:程序博客网 时间:2024/05/18 00:35

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
   );

0 0