如何获取表单的屏幕截图

时间:2011-02-26 01:23:54

标签: c# .net winforms

输出活动表单屏幕截图的任何方法?

8 个答案:

答案 0 :(得分:25)

使用Control.DrawToBitmap()方法。例如:

    private void timer1_Tick(object sender, EventArgs e) {
        var frm = Form.ActiveForm;
        using (var bmp = new Bitmap(frm.Width, frm.Height)) {
            frm.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
            bmp.Save(@"c:\temp\screenshot.png");
        }
    }

答案 1 :(得分:20)

.NET支持更简单的答案:

Control.DrawToBitmap

答案 2 :(得分:6)

试试这个:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;

namespace ScreenshotCapturer
{
    public partial class Form1 : Form
    {
        private static Bitmap bmpScreenshot;
        private static Graphics gfxScreenshot;

        public Form1()
        {
            InitializeComponent();
        }

        private void btnCapture_Click(object sender, EventArgs e)
        {
            // If the user has choosed a path where to save the screenshot
            if (saveScreenshot.ShowDialog() == DialogResult.OK)
            {
                // Hide the form so that it does not appear in the screenshot
                this.Hide();
                // Set the bitmap object to the size of the screen
                bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
                // Create a graphics object from the bitmap
                gfxScreenshot = Graphics.FromImage(bmpScreenshot);
                // Take the screenshot from the upper left corner to the right bottom corner
                gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
                // Save the screenshot to the specified path that the user has chosen
                bmpScreenshot.Save(saveScreenshot.FileName, ImageFormat.Png);
                // Show the form again
                this.Show();
            }
        }
    }
}

答案 3 :(得分:2)

以下是您可以使用的扩展方法:

    #region Interop

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr hdc, PRF_FLAGS drawingOptions);

    const uint WM_PRINT = 0x317;

    [Flags]
    enum PRF_FLAGS : uint
    {
        CHECKVISIBLE = 0x01,
        CHILDREN = 0x02,
        CLIENT = 0x04,
        ERASEBKGND = 0x08,
        NONCLIENT = 0x10,
        OWNED = 0x20
    }

    #endregion

    public static Image CaptureImage(this Control control)
    {
        Image img = new Bitmap(control.Width, control.Height);
        using (Graphics g = Graphics.FromImage(img))
        {
            SendMessage(
               control.Handle,
               WM_PRINT,
               g.GetHdc(),
               PRF_FLAGS.CLIENT | PRF_FLAGS.NONCLIENT | PRF_FLAGS.ERASEBKGND);
        }
        return img;
    }

Form继承自Control,因此您也可以在表单上使用它。

答案 4 :(得分:2)

因为Control.DrawToBitmap有一些限制(最值得注意的是以相反的顺序绘制子控件),我已经做了这个替代方案。变量_control是您要复制的WinForms控件/表单。

using (Bitmap bitmap = new Bitmap(width, height)) {
    using (Graphics gb = Graphics.FromImage(bitmap))
    using (Graphics gc = Graphics.FromHwnd(_control.Handle)) {

          IntPtr hdcDest = IntPtr.Zero;
          IntPtr hdcSrc = IntPtr.Zero;

          try {
              hdcDest = gb.GetHdc();
              hdcSrc = gc.GetHdc();

              BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRC_COPY);
          } finally {
              if (hdcDest != IntPtr.Zero) gb.ReleaseHdc(hdcDest);
              if (hdcSrc != IntPtr.Zero) gc.ReleaseHdc(hdcSrc);
          }
      }

      bitmap.Save(...);
}

[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BitBlt(
    [In()] System.IntPtr hdc, int x, int y, int cx, int cy,
    [In()] System.IntPtr hdcSrc, int x1, int y1, uint rop);

private const int SRC_COPY = 0xCC0020;

答案 5 :(得分:1)

         this.Opacity = 0;
        Rectangle bounds = Screen.GetBounds(Point.Empty);

        // create the bitmap to copy the screen shot to
        Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);

        // now copy the screen image to the graphics device from the bitmap
        using (Graphics gr = Graphics.FromImage(bitmap))
        {

            gr.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);          
        }
        this.Opacity = 100;

现在只是

        gr.Save(@"c\pic.jpg",ImageFormat.jpg);

答案 6 :(得分:1)

这会将活动窗口的屏幕截图保存到C:驱动器。

SendKeys.Send("")用于将按键发送到计算机。在这种情况下,%用于按Alt{PRTSC}显然按下键盘上的Print Screen按钮。

希望这有助于某人!

private void printScreenButton_Click(object sender, EventArgs e)
{
    SendKeys.Send("%{PRTSC}");
    Image img = Clipboard.GetImage();
    img.Save(@"C:\\testprintscreen.jpg");
}

答案 7 :(得分:1)

here is:




       public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter

    [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 bool StretchBlt(
          IntPtr hdcDest,      // handle to destination DC
          int nXOriginDest, // x-coord of destination upper-left corner
          int nYOriginDest, // y-coord of destination upper-left corner
          int nWidthDest,   // width of destination rectangle
          int nHeightDest,  // height of destination rectangle
          IntPtr hdcSrc,       // handle to source DC
          int nXOriginSrc,  // x-coord of source upper-left corner
          int nYOriginSrc,  // y-coord of source upper-left corner
          int nWidthSrc,    // width of source rectangle
          int nHeightSrc,   // height of source rectangle
          int dwRop       // raster operation code
        );


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



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

    private void run_test()
    {

        Rectangle rc = new Rectangle();
        Image img = ScreenToImage(ref rc, false);
        img.Save(@"C:\Users\ssaamm\Desktop\Capt44ure.JPG", System.Drawing.Imaging.ImageFormat.Jpeg);
        img.Dispose();

    }


    private Image ScreenToImage(ref Rectangle rcDest, bool IsPapaer)
    {
        IntPtr handle = this.Handle;

        //this.Handle
        // get te hDC of the target window
        IntPtr hdcSrc = GetWindowDC(handle);
        // get the size
        RECT windowRect = new RECT();
        GetWindowRect(handle, ref windowRect);
        int nWidth = windowRect.right - windowRect.left;
        int nHeight = windowRect.bottom - windowRect.top;

        if (IsPapaer)
        {
            float fRate = (float)rcDest.Width / nWidth;
            //float fHeight = nHeight * fRate;
            //rcDest.Height = (int)(nHeight * fRate);
            //rcDest.Width = (int)(rcDest.Width);// * fRate);
            rcDest.X = 0;
            rcDest.Y = 0;
            rcDest.Height = (int)(nHeight * fRate);
            //rcDest.Width = (int)(nWidth * fRate);
        }
        else
        {
            rcDest.X = 0;
            rcDest.Y = 0;
            rcDest.Height = nHeight;
            rcDest.Width = nWidth;
        }

        // create a device context we can copy to
        IntPtr hdcDest = CreateCompatibleDC(hdcSrc);
        // create a bitmap we can copy it to,
        // using GetDeviceCaps to get the width/height
        IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, rcDest.Width, rcDest.Height);
        // select the bitmap object
        IntPtr hOld = SelectObject(hdcDest, hBitmap);
        // bitblt over
        StretchBlt(hdcDest, rcDest.X, rcDest.Y, rcDest.Width, rcDest.Height, hdcSrc, 0, 0, nWidth, nHeight, SRCCOPY);
        // restore selection
        SelectObject(hdcDest, hOld);
        // clean up 
        DeleteDC(hdcDest);
        ReleaseDC(handle, hdcSrc);

        // get a .NET image object for it
        Image img = Image.FromHbitmap(hBitmap);
        // free up the Bitmap object
        DeleteObject(hBitmap);
        return img;
    }