最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用C#自制一個截屏工具

 更新時間:2026年04月27日 09:20:40   作者:hixiong123  
ScreenCapture?是一個輔助類,用于在 Windows Forms 應(yīng)用程序中實現(xiàn)全屏區(qū)域截圖功能,本文給大家介紹了如何使用C#自制一個截屏工具,需要的朋友可以參考下

概述

ScreenCapture 是一個輔助類,用于在 Windows Forms 應(yīng)用程序中實現(xiàn)全屏區(qū)域截圖功能。它提供了一個半透明覆蓋層,用戶可以按下鼠標(biāo)左鍵并拖動選擇一個矩形區(qū)域,松開鼠標(biāo)后即可截取該區(qū)域的圖像。

該類的設(shè)計初衷是配合 PictureBox 控件,讓用戶通過“截圖”按鈕快速截取屏幕任意區(qū)域,并自動加載到圖片展示控件中。

主要功能

  • 全屏半透明遮罩,高亮顯示鼠標(biāo)拖拽的選區(qū)
  • 支持 ESC 鍵取消截圖
  • 返回截圖的 Bitmap 對象,可進(jìn)一步轉(zhuǎn)換為 OpenCvSharp.Mat 或其他圖像格式
  • 實現(xiàn)了 IDisposable 接口,便于資源管理

使用方法

1. 在項目中添加文件

將 ScreenCapture.cs 添加到WinForms 項目中。

2. 基本調(diào)用示例

using (var screenCapture = new ScreenCapture())
{
    Bitmap capturedBmp = screenCapture.CaptureScreen();
    if (capturedBmp != null)
    {
        // 將 Bitmap 轉(zhuǎn)換為 OpenCvSharp.Mat(需引用 OpenCvSharp.Extensions)
        Mat mat = BitmapConverter.ToMat(capturedBmp);
        // 顯示到 PictureBox
        pictureBox1.Image?.Dispose();
        pictureBox1.Image = mat.ToBitmap();
    }
}

3. 配合按鈕點擊事件使用(標(biāo)準(zhǔn)用法)

private void btnScreenshot_Click(object sender, EventArgs e)
{
    // 隱藏當(dāng)前窗體,避免遮擋截圖界面
    this.Hide();
    // 等待窗體完全隱藏
    System.Threading.Thread.Sleep(200);
    
    using (var cap = new ScreenCapture())
    {
        var bmp = cap.CaptureScreen();
        if (bmp != null)
        {
            // 處理截圖結(jié)果,例如顯示在 PictureBox 中
            pictureBox1.Image?.Dispose();
            pictureBox1.Image = bmp;
        }
    }
    
    // 重新顯示主窗體
    this.Show();
}

4. 其他示例

private void btnScreenshotOcr_Click(object sender, EventArgs e)
{
    TakeScreenshot(img =>
    {
        currentOcrImage?.Dispose();
        currentOcrImage = img.Clone();
        ShowImage(pictureBoxOcr, img);
    });
}

private void TakeScreenshot(Action<Mat> onCaptured)
{
    this.Hide();
    System.Threading.Thread.Sleep(200);
    using (var cap = new ScreenCapture())
    {
        var bmp = cap.CaptureScreen();
        if (bmp != null)
        {
            Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmp);
            onCaptured?.Invoke(mat);
        }
    }
    this.Show();
}

注意事項

截圖期間主窗體隱藏
為了獲得純凈的截圖背景,通常需要將主窗體隱藏(this.Hide()),截圖完成后再顯示(this.Show())。注意等待一小段時間(如 200ms)確保窗體完全隱藏。

屏幕 DPI 縮放
在高 DPI 環(huán)境下,Graphics.CopyFromScreen 會按物理屏幕坐標(biāo)截取,通常沒有問題。如果需要考慮縮放比例,可以進(jìn)一步調(diào)整。

取消截圖
用戶按下 ESC 鍵后,DialogResult 會返回 Cancel,CaptureScreen() 返回 null。您的代碼應(yīng)當(dāng)處理 null 情況。

線程安全
ScreenCapture 內(nèi)部使用 ShowDialog() 顯示模態(tài)覆蓋層,必須在 UI 線程調(diào)用。不要在后臺線程中直接調(diào)用。

資源釋放
類實現(xiàn)了 IDisposable,務(wù)必使用 using 語句或手動調(diào)用 Dispose() 釋放內(nèi)部資源(如覆蓋層窗體)。

內(nèi)部結(jié)構(gòu)說明

  • SelectionOverlay 是一個繼承自 Form 的內(nèi)部類,負(fù)責(zé)顯示半透明全屏遮罩,處理鼠標(biāo)拖拽和鍵盤事件。
  • SelectedRegion 屬性記錄了用戶選中的矩形區(qū)域(屏幕坐標(biāo))。
  • 截圖操作通過 Graphics.CopyFromScreen 將選中區(qū)域復(fù)制到 Bitmap 中。

依賴項

  • 需要引用 System.Drawing 和 System.Windows.Forms。
  • 如需轉(zhuǎn)換為 Mat,還需要 OpenCvSharp.Extensions(可選)。
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
? ? /// <summary>
? ? /// 屏幕截圖輔助類,提供全屏區(qū)域截圖功能。
? ? /// 使用方法:
? ? /// <code>
? ? /// using (var cap = new ScreenCapture())
? ? /// {
? ? /// ? ? Bitmap bmp = cap.CaptureScreen();
? ? /// ? ? if (bmp != null)
? ? /// ? ? {
? ? /// ? ? ? ? // 處理截圖
? ? /// ? ? }
? ? /// }
? ? /// </code>
? ? /// </summary>
? ? public class ScreenCapture : IDisposable
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 啟動全屏選區(qū)截圖,返回用戶選中的區(qū)域圖像。
? ? ? ? /// </summary>
? ? ? ? /// <returns>截取到的 Bitmap 圖像;如果用戶取消操作或選區(qū)無效,返回 null。</returns>
? ? ? ? public Bitmap CaptureScreen()
? ? ? ? {
? ? ? ? ? ? // 創(chuàng)建并顯示選區(qū)覆蓋層窗體(模態(tài)對話框)
? ? ? ? ? ? using (var overlay = new SelectionOverlay())
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 顯示對話框,等待用戶操作
? ? ? ? ? ? ? ? var result = overlay.ShowDialog();
? ? ? ? ? ? ? ? // 用戶確認(rèn)且區(qū)有效
? ? ? ? ? ? ? ? if (result == DialogResult.OK && overlay.SelectedRegion != Rectangle.Empty)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? Rectangle bounds = overlay.SelectedRegion;
? ? ? ? ? ? ? ? ? ? // 創(chuàng)建與選區(qū)相同尺寸的 Bitmap
? ? ? ? ? ? ? ? ? ? Bitmap bmp = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
? ? ? ? ? ? ? ? ? ? using (Graphics g = Graphics.FromImage(bmp))
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? // 從屏幕復(fù)制選區(qū)內(nèi)容到 Bitmap
? ? ? ? ? ? ? ? ? ? ? ? g.CopyFromScreen(bounds.X, bounds.Y, 0, 0, bounds.Size);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? return bmp;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// 全屏選區(qū)覆蓋層窗體(內(nèi)部類),提供半透明背景和鼠標(biāo)拖拽選擇功能。
? ? ? ? /// </summary>
? ? ? ? private class SelectionOverlay : Form
? ? ? ? {
? ? ? ? ? ? /// <summary>用戶最終選中的屏幕區(qū)域(屏幕坐標(biāo))。</summary>
? ? ? ? ? ? public Rectangle SelectedRegion { get; private set; } = Rectangle.Empty;
? ? ? ? ? ? private Point startPoint; ? ? ? ? ?// 鼠標(biāo)按下時的起始點
? ? ? ? ? ? private bool selecting = false; ? ? // 是否正在拖拽選擇中
? ? ? ? ? ? private Rectangle currentRect; ? ? ?// 當(dāng)前拖拽的矩形
? ? ? ? ? ? private Pen selectionPen; ? ? ? ? ? // 繪制選擇框的畫筆
? ? ? ? ? ? /// <summary>
? ? ? ? ? ? /// 初始化覆蓋層窗體。
? ? ? ? ? ? /// </summary>
? ? ? ? ? ? public SelectionOverlay()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 無邊框、最大化填滿屏幕
? ? ? ? ? ? ? ? this.FormBorderStyle = FormBorderStyle.None;
? ? ? ? ? ? ? ? this.WindowState = FormWindowState.Maximized;
? ? ? ? ? ? ? ? // 黑色半透明背景,實現(xiàn)“遮罩”效果
? ? ? ? ? ? ? ? this.BackColor = Color.Black;
? ? ? ? ? ? ? ? this.Opacity = 0.6; ? ? ?// 透明度 0.6,突出選框區(qū)域
? ? ? ? ? ? ? ? this.DoubleBuffered = true; ? // 減少閃爍
? ? ? ? ? ? ? ? this.TopMost = true; ? ? ? ? ?// 置頂,覆蓋所有窗口
? ? ? ? ? ? ? ? this.Cursor = Cursors.Cross; ?// 十字光標(biāo),適合選區(qū)操作
? ? ? ? ? ? ? ? this.KeyPreview = true; ? ? ? // 讓窗體優(yōu)先接收鍵盤事件(如 ESC)
? ? ? ? ? ? ? ? // 初始化畫筆:半透明綠色,2像素寬
? ? ? ? ? ? ? ? selectionPen = new Pen(Color.FromArgb(100, 0, 255, 0), 2);
? ? ? ? ? ? ? ? // 綁定事件
? ? ? ? ? ? ? ? this.MouseDown += OnMouseDown;
? ? ? ? ? ? ? ? this.MouseMove += OnMouseMove;
? ? ? ? ? ? ? ? this.MouseUp += OnMouseUp;
? ? ? ? ? ? ? ? this.Paint += OnPaint;
? ? ? ? ? ? ? ? this.KeyDown += OnKeyDown;
? ? ? ? ? ? }
? ? ? ? ? ? /// <summary>
? ? ? ? ? ? /// 鼠標(biāo)按下:開始選區(qū)。
? ? ? ? ? ? /// </summary>
? ? ? ? ? ? private void OnMouseDown(object sender, MouseEventArgs e)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (e.Button == MouseButtons.Left)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? startPoint = e.Location; ? ? ? ? ? // 記錄起始點
? ? ? ? ? ? ? ? ? ? selecting = true; ? ? ? ? ? ? ? ? ?// 進(jìn)入選擇模式
? ? ? ? ? ? ? ? ? ? currentRect = new Rectangle(startPoint, new Size(0, 0)); // 初始矩形為空
? ? ? ? ? ? ? ? ? ? Invalidate(); ? ? ? ? ? ? ? ? ? ? ?// 觸發(fā)重繪
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? /// <summary>
? ? ? ? ? ? /// 鼠標(biāo)移動:更新當(dāng)前選區(qū)矩形并重繪。
? ? ? ? ? ? /// </summary>
? ? ? ? ? ? private void OnMouseMove(object sender, MouseEventArgs e)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (selecting)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? // 計算矩形的正確邊界(支持向左/向上拖拽)
? ? ? ? ? ? ? ? ? ? int x = Math.Min(startPoint.X, e.X);
? ? ? ? ? ? ? ? ? ? int y = Math.Min(startPoint.Y, e.Y);
? ? ? ? ? ? ? ? ? ? int w = Math.Abs(startPoint.X - e.X);
? ? ? ? ? ? ? ? ? ? int h = Math.Abs(startPoint.Y - e.Y);
? ? ? ? ? ? ? ? ? ? currentRect = new Rectangle(x, y, w, h);
? ? ? ? ? ? ? ? ? ? Invalidate(); ? // 觸發(fā) OnPaint 重繪
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? /// <summary>
? ? ? ? ? ? /// 鼠標(biāo)釋放:完成選區(qū)。
? ? ? ? ? ? /// </summary>
? ? ? ? ? ? private void OnMouseUp(object sender, MouseEventArgs e)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (e.Button == MouseButtons.Left && selecting && currentRect.Width > 5 && currentRect.Height > 5)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? // 選區(qū)寬度和高度至少為5像素,避免誤觸
? ? ? ? ? ? ? ? ? ? SelectedRegion = currentRect; ? ? ? ? ? // 保存選區(qū)
? ? ? ? ? ? ? ? ? ? this.DialogResult = DialogResult.OK; ? ?// 設(shè)置對話框結(jié)果為 OK
? ? ? ? ? ? ? ? ? ? this.Close(); ? ? ? ? ? ? ? ? ? ? ? ? ? // 關(guān)閉覆蓋層
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? selecting = false; ?// 退出選擇模式
? ? ? ? ? ? }
? ? ? ? ? ? /// <summary>
? ? ? ? ? ? /// 繪制覆蓋層內(nèi)容:在選區(qū)邊緣繪制矩形框。
? ? ? ? ? ? /// </summary>
? ? ? ? ? ? private void OnPaint(object sender, PaintEventArgs e)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (selecting && currentRect.Width > 0 && currentRect.Height > 0)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? // 繪制矩形框(僅邊框,不填充)
? ? ? ? ? ? ? ? ? ? e.Graphics.DrawRectangle(selectionPen, currentRect);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? /// <summary>
? ? ? ? ? ? /// 鍵盤按下:按 ESC 鍵取消截圖。
? ? ? ? ? ? /// </summary>
? ? ? ? ? ? private void OnKeyDown(object sender, KeyEventArgs e)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (e.KeyCode == Keys.Escape)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? this.DialogResult = DialogResult.Cancel; ?// 取消操作
? ? ? ? ? ? ? ? ? ? this.Close();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? /// <summary>
? ? ? ? ? ? /// 釋放資源。
? ? ? ? ? ? /// </summary>
? ? ? ? ? ? protected override void Dispose(bool disposing)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (disposing)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? selectionPen?.Dispose(); ?// 釋放畫筆
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? base.Dispose(disposing);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// 實現(xiàn) IDisposable 接口(當(dāng)前類無額外需要釋放的資源,但保留方法以備將來擴(kuò)展)。
? ? ? ? /// </summary>
? ? ? ? public void Dispose()
? ? ? ? {
? ? ? ? ? ? // 無托管資源需要釋放,但為了接口完整性保留空方法
? ? ? ? }
? ? }
}

到此這篇關(guān)于使用C#自制一個截屏工具的文章就介紹到這了,更多相關(guān)C#截屏工具內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

文登市| 姚安县| 二手房| 定安县| 英超| 时尚| 谢通门县| 太白县| 玉田县| 贵阳市| 福安市| 合作市| 阿城市| 化德县| 尼玛县| 抚顺市| 桑植县| 瓮安县| 麟游县| 鄄城县| 桦南县| 抚州市| 梓潼县| 佛坪县| 文成县| 建始县| 长兴县| 江津市| 德阳市| 阳江市| 永城市| 江门市| 十堰市| 伊金霍洛旗| 鱼台县| 博爱县| 五指山市| 平南县| 赣州市| 隆化县| 堆龙德庆县|