如何通过 C# 将桌面截屏为图片?

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过 C# 将桌面截屏为图片?相关的知识,希望对你有一定的参考价值。

咨询区

  • Omar Abid

我想通过代码获取当前的电脑屏幕并保存为一张图片,就好像键盘的 截屏 按钮功能,请问这该如何实现?我没有好思路。

回答区

  • Gary Willoughby

如果你的程序是 framework >2.0 的话,完全可以使用 CopyFromScreen() 方法,参考如下代码:

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

更详细的资料可参考:http://www.geekpedia.com/tutorial181_Capturing-screenshots-using-Csharp.html

  • colton7909

要想完美的通过代码截屏,通常有两个坑需要解决。

  1. 默认情况下是不能截图到扩展屏的,也就是 多显示器 的情况。

  2. 当显示屏设置了扩大或缩小展示,比如 125%,150% ,那么 Screen 返回的数值会是错误的。

解决这两个问题,最好的方式就是通过 p/invoke 调用底层的 win32 api 来实现,参考如下代码:

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;
    

更多资料请参考:https://stackoverflow.com/a/36864741/987968 http://pinvoke.net/default.aspx/user32/EnumDisplaySettings.html?diff=y

点评区

没想到截个屏还有这么多坑需要解决,不过用了 win32 api,那就限定了 windows 平台,不知道大家可有什么好的跨平台解决方案呢?

以上是关于如何通过 C# 将桌面截屏为图片?的主要内容,如果未能解决你的问题,请参考以下文章

保存Simulink仿真模型为图片或者PDF的方法

C#截屏

C# wpf 使用GDI+实现截屏

mac如何截屏并保存

VC++屏幕捕获并保存成图片(附源码)

mac如何截屏