如何通过 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:
要想完美的通过代码截屏,通常有两个坑需要解决。
默认情况下是不能截图到扩展屏的,也就是
多显示器
的情况。当显示屏设置了扩大或缩小展示,比如
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# 将桌面截屏为图片?的主要内容,如果未能解决你的问题,请参考以下文章