C# WinForm使用CopyFromScreen实现屏幕截图
本文介绍利用 C# GDI+ 技术在 Windows 窗体应用中实现桌面屏幕截图的方法,核心在于调用 User32.dll 获取屏幕尺寸并结合 CopyFromScreen 指令完成图像抓取。
原理与准备
C# 本身不直接内置“一键截取整个桌面”的高层 API,但可以通过 System.Drawing.Graphics.CopyFromScreen 方法,配合非托管的 User32.dll 库来获取当前操作系统的屏幕参数(如宽、高),从而定义截图的区域大小。整个过程不需要第三方插件,适用于大多数 .NET Framework 环境的 WinForm 项目。
实现全屏桌面截图
第一步:引入外部函数与定义资源
在窗体类中声明对 user32.dll 的 GetSystemMetrics 引用,这将用于精准获取显示器当前的物理分辨率,避免在不同缩放或大屏下出现截屏不全的问题。
[DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
private static extern int GetSystemMetrics(int mVal);
第二步:编写核心截图逻辑
当触发按钮事件时,创建对应屏幕尺寸的 Bitmap 对象,并通过 Graphics.FromImage 获取绘图上下文。调用 g.CopyFromScreen(0, 0, 0, 0, _Source.Size) 即可将源坐标 (0,0) 的屏幕画面拷贝至目标内存位图。
private void button1_Click(object sender, EventArgs e)
{
// 1. 获取屏幕的实际分辨率作为截图尺寸
Bitmap _Source = new Bitmap(GetSystemMetrics(0), GetSystemMetrics(1));
using (Graphics g = Graphics.FromImage(_Source))
{
// 2. 执行拷贝:源X, 源Y, 目标X, 目标Y, 尺寸
g.CopyFromScreen(0, 0, 0, 0, _Source.Size);
g.Dispose();
}
// 3. 将截图结果绑定到图片显示控件
pictureBox1.Image = _Source;
}
第三步:配置界面设计器代码
为了让代码正常运行,需要在窗体的初始化过程中正确挂载 button1 的点击事件,并添加用于展示图片的 pictureBox1。
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(24, 12);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "抓取桌面";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click); // 绑定点击事件
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point(105, 12);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(515, 306);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox1.TabIndex = 1;
this.pictureBox1.TabStop = false;
...
}
进阶:截取指定局部区域
如果只需要截取屏幕上某个固定大小的窗口或特定位置(例如左上角 300x200 的区域),可以免去获取全局尺寸的操作,直接硬编码 Size 参数。
private void button1_Click(object sender, EventArgs e)
{
// 创建一个 300x200 的目标画布
Image memory = new Bitmap(300, 200);
Graphics g = Graphics.FromImage(memory);
// 只拷贝屏幕左上角的 300x200 区域
g.CopyFromScreen(0, 0, 0, 0, new Size(300, 200));
pictureBox1.Image = memory;
}
常见问题排查
- 黑屏现象:如果使用 Remote Desktop 服务或其他虚拟环境连接服务器,
GetSystemMetrics可能返回的是远程会话的虚拟分辨率而非物理显卡渲染的桌面,导致截屏异常。 - UI线程卡顿:在全屏截屏时,
CopyFromScreen会瞬间阻塞当前 UI 线程约 0.1~0.5 秒。对于高分辨率显示器或复杂界面,建议在BackgroundWorker或async/await任务中异步执行,以防软件无响应。
以上就是基于C#实现屏幕桌面截图的详细内容,更多关于C#屏幕桌面截图的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









