C# 将屏幕捕获到位图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/362986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:35:59  来源:igfitidea点击:

Capture the Screen into a Bitmap

c#.netscreenshot

提问by Omar Abid

I want to capture the screen in my code to get an image - like using the 'print screen' button on the keyboard .

我想在我的代码中捕获屏幕以获取图像 - 就像使用键盘上的“打印屏幕”按钮一样。

Does anyone have an idea how to do this? I have no starting point.

有谁知道如何做到这一点?我没有起点。

采纳答案by Gary Willoughby

If using the .NET 2.0 (or later) framework you can use the CopyFromScreen()method detailed here:

如果使用 .NET 2.0(或更高版本)框架,您可以使用CopyFromScreen()此处详述的方法:

http://www.geekpedia.com/tutorial181_Capturing-screenshots-using-Csharp.html

http://www.geekpedia.com/tutorial181_Capturing-screenshots-using-Csharp.html

//Create a new bitmap.
var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                               Screen.PrimaryScreen.Bounds.Height,
                               PixelFormat.Format32bppArgb);

// Create a graphics object from the bitmap.
var 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("Screenshot.png", ImageFormat.Png);

回答by Skhanpara

// Use this version to capture the full extended desktop (i.e. multiple screens)

Bitmap screenshot = new Bitmap(SystemInformation.VirtualScreen.Width, 
                               SystemInformation.VirtualScreen.Height, 
                               PixelFormat.Format32bppArgb);
Graphics screenGraph = Graphics.FromImage(screenshot);
screenGraph.CopyFromScreen(SystemInformation.VirtualScreen.X, 
                           SystemInformation.VirtualScreen.Y, 
                           0, 
                           0, 
                           SystemInformation.VirtualScreen.Size, 
                           CopyPixelOperation.SourceCopy);

screenshot.Save("Screenshot.png", System.Drawing.Imaging.ImageFormat.Png);

回答by user4340666

Try thiscode

试试这个代码

Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics gr = Graphics.FromImage(bmp);
gr.CopyFromScreen(0, 0, 0, 0, bmp.Size);
pictureBox1.Image = bmp;
bmp.Save("img.png",System.Drawing.Imaging.ImageFormat.Png);

回答by trung thong hoang

Bitmap memoryImage;
//Set full width, height for image
memoryImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                       Screen.PrimaryScreen.Bounds.Height,
                       PixelFormat.Format32bppArgb);
Size s = new Size(memoryImage.Width, memoryImage.Height);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
memoryGraphics.CopyFromScreen(0, 0, 0, 0, s);
string str = "";
try
{
    str = string.Format(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
          @"\Screenshot.png");//Set folder to save image
}
catch { };
memoryImage.save(str);

回答by colton7909

I had two problems with the accepted answer.

我对接受的答案有两个问题。

  1. It doesn't capture all screens in a multi-monitor setup.
  2. The width and height returned by the Screenclass are incorrect when display scaling is used and your application is not declared dpiAware.
  1. 它不会在多显示器设置中捕获所有屏幕。
  2. Screen当使用显示缩放并且您的应用程序未声明为dpiAware时,类返回的宽度和高度不正确。

Here's my updated solution using the Screen.AllScreensstatic property and calling EnumDisplaySettingsusing p/invoke to get the real screen resolution.

这是我使用Screen.AllScreens静态属性并EnumDisplaySettings使用 p/invoke 调用以获得真实屏幕分辨率的更新解决方案。

using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;

class Program
{
    const int ENUM_CURRENT_SETTINGS = -1;

    static void Main()
    {
        foreach (Screen screen in Screen.AllScreens)
        {
            DEVMODE dm = new DEVMODE();
            dm.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE));
            EnumDisplaySettings(screen.DeviceName, ENUM_CURRENT_SETTINGS, ref dm);

            using (Bitmap bmp = new Bitmap(dm.dmPelsWidth, dm.dmPelsHeight))
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.CopyFromScreen(dm.dmPositionX, dm.dmPositionY, 0, 0, bmp.Size);
                bmp.Save(screen.DeviceName.Split('\').Last() + ".png");
            }
        }
    }

    [DllImport("user32.dll")]
    public static extern bool EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);

    [StructLayout(LayoutKind.Sequential)]
    public struct DEVMODE
    {
        private const int CCHDEVICENAME = 0x20;
        private const int CCHFORMNAME = 0x20;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
        public string dmDeviceName;
        public short dmSpecVersion;
        public short dmDriverVersion;
        public short dmSize;
        public short dmDriverExtra;
        public int dmFields;
        public int dmPositionX;
        public int dmPositionY;
        public ScreenOrientation dmDisplayOrientation;
        public int dmDisplayFixedOutput;
        public short dmColor;
        public short dmDuplex;
        public short dmYResolution;
        public short dmTTOption;
        public short dmCollate;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
        public string dmFormName;
        public short dmLogPixels;
        public int dmBitsPerPel;
        public int dmPelsWidth;
        public int dmPelsHeight;
        public int dmDisplayFlags;
        public int dmDisplayFrequency;
        public int dmICMMethod;
        public int dmICMIntent;
        public int dmMediaType;
        public int dmDitherType;
        public int dmReserved1;
        public int dmReserved2;
        public int dmPanningWidth;
        public int dmPanningHeight;
    }
}

References:

参考:

https://stackoverflow.com/a/36864741/987968http://pinvoke.net/default.aspx/user32/EnumDisplaySettings.html?diff=y

https://stackoverflow.com/a/36864741/987968 http://pinvoke.net/default.aspx/user32/EnumDisplaySettings.html?diff=y