最新国产好看的视频,伊人天堂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 對象,可進一步轉(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)截取,通常沒有問題。如果需要考慮縮放比例,可以進一步調(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; ? ? ? ? ? ? ? ? ?// 進入選擇模式
? ? ? ? ? ? ? ? ? ? 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)前類無額外需要釋放的資源,但保留方法以備將來擴展)。
? ? ? ? /// </summary>
? ? ? ? public void Dispose()
? ? ? ? {
? ? ? ? ? ? // 無托管資源需要釋放,但為了接口完整性保留空方法
? ? ? ? }
? ? }
}

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

相關(guān)文章

最新評論

青冈县| 清新县| 汝南县| 内乡县| 夹江县| 枣阳市| 镇江市| 伽师县| 宝丰县| 盐池县| 蓬溪县| 玉屏| 南岸区| 瑞昌市| 达孜县| 万安县| 宜都市| 观塘区| 衡东县| 和田市| 苏尼特右旗| 十堰市| 丁青县| 遂昌县| 襄樊市| 河源市| 贵德县| 海盐县| 赣州市| 丘北县| 浑源县| 柳林县| 新巴尔虎左旗| 富民县| 怀仁县| 偏关县| 锡林浩特市| 益阳市| 平舆县| 建瓯市| 衡山县|