将屏幕捕获到位图中

Oma*_*bid 62 .net c# screenshot

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

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

Gar*_*hby 106

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

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);
Run Code Online (Sandbox Code Playgroud)

  • 是的,看一下.NET Screen对象以获取其他屏幕.请注意,在上面的调用中,我使用`Screen.PrimaryScreen`来获取主屏幕?您可以使用`Screen.AllScreens`来获取所有这些数组.`Screen.AllScreens [n] .Bounds.Width`等...... (3认同)
  • 如果更改显示设置**将所有项目的大小**更改为**更大**,代码只能捕获部分屏幕.怎么解决? (2认同)

col*_*909 9

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

  1. 它不会在多显示器设置中捕获所有屏幕。
  2. Screen当使用显示缩放并且您的应用程序未声明为dpiAware时,类返回的宽度和高度不正确。

这是我使用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

参考:

/sf/answers/2580531901/ http://pinvoke.net/default.aspx/user32/EnumDisplaySettings.html?diff=y


小智 6

// 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);
Run Code Online (Sandbox Code Playgroud)

  • 运行良好,但有一般的用户界面冻结.与需要每秒分析屏幕10-20次的项目(如我的)不兼容. (3认同)