C# WinForm使用CopyFromScreen实现屏幕截图

青禾
青禾
发布时间:2026-10-15 | 3人浏览过
原创

本文介绍利用 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#屏幕桌面截图的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表