首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 實作類似 QQ 的螢幕截圖工具:全螢幕遮罩與矩形選取

     編輯:關於C#

功能流程

  1. 點擊按鈕 → 擷取全螢幕影像存為 Bitmap。
  2. 開啟無框全螢幕視窗(FormBorderStyle=None,WindowState=Maximized),以截圖為背景。
  3. 滑鼠拖曳繪製選取矩形,右鍵取消,雙擊確認。
  4. 確認時將選取區域複製到新 Bitmap,存入剪貼簿,關閉視窗。

核心程式碼結構

主表單:啟動截圖


private void btnCapture_Click(object sender, EventArgs e)
{
    Bitmap screen = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);
    using (Graphics g = Graphics.FromImage(screen))
        g.CopyFromScreen(Point.Empty, Point.Empty, Screen.AllScreens[0].Bounds.Size);

    new SelectionForm { BackgroundImage = screen }.Show();
}

選取視窗:SelectionForm


public partial class SelectionForm : Form
{
    private Graphics _g;          // 視窗繪圖介面
    private Pen _pen = new Pen(Color.Blue, 2);
    private bool _mouseDown, _rectReady;
    private Image _baseImage;     // 原始螢幕截圖
    private Rectangle _rect;      // 目前選取矩形
    private Point _startPt;       // 滑鼠按下位置
    private int _lastX, _lastY;   // 移動時上一座標

    public SelectionForm()
    {
        InitializeComponent();
        FormBorderStyle = FormBorderStyle.None;
        WindowState = FormWindowState.Maximized;
        DoubleBuffered = true;
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        _g = CreateGraphics();
        _baseImage = BackgroundImage;
        _rect = Rectangle.Empty;
        _rectReady = false;
    }

    // 滑鼠按下:開始選取或拖曳現有矩形
    protected override void OnMouseDown(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            _mouseDown = true;
            if (!_rectReady) { _rect.Location = e.Location; _startPt = e.Location; }
            else { _lastX = e.X; _lastY = e.Y; }
        }
        else if (e.Button == MouseButtons.Right && !_rectReady)
            Close(); // 右鍵取消
    }

    // 滑鼠移動:即時繪製/移動矩形
    protected override void OnMouseMove(MouseEventArgs e)
    {
        if (!_rectReady && _mouseDown) DrawSelectionRect(e.X, e.Y);
        else if (_rectReady && _rect.Contains(e.Location) && _mouseDown) MoveRect(e.X, e.Y);
    }

    // 滑鼠釋放:完成選取
    protected override void OnMouseUp(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left) { _mouseDown = false; _rectReady = true; }
    }

    // 雙擊確認:複製到剪貼簿並關閉
    protected override void OnDoubleClick(EventArgs e)
    {
        if (_rectReady && _rect.Contains(PointToClient(MousePosition)))
        {
            using (Bitmap bmp = new Bitmap(_rect.Width, _rect.Height))
            using (Graphics g = Graphics.FromImage(bmp))
                g.CopyFromScreen(_rect.Location, Point.Empty, _rect.Size);
            Clipboard.SetImage(bmp);
            Close();
        }
    }

    // 繪製選取框(雙緩衝手動實作)
    private void DrawSelectionRect(int x, int y)
    {
        using (Bitmap buffer = new Bitmap(_baseImage))
        using (Graphics g = Graphics.FromImage(buffer))
        {
            UpdateRect(_startPt, new Point(x, y));
            g.DrawRectangle(_pen, _rect);
            _g.DrawImageUnscaled(buffer, 0, 0);
        }
    }

    private void MoveRect(int x, int y)
    {
        int dx = x - _lastX, dy = y - _lastY;
        _rect.Offset(dx, dy);
        _lastX = x; _lastY = y;
        using (Bitmap buffer = new Bitmap(_baseImage))
        using (Graphics g = Graphics.FromImage(buffer))
        {
            g.DrawRectangle(_pen, _rect);
            _g.DrawImageUnscaled(buffer, 0, 0);
        }
    }

    private void UpdateRect(Point p1, Point p2)
    {
        _rect.X = Math.Min(p1.X, p2.X);
        _rect.Y = Math.Min(p1.Y, p2.Y);
        _rect.Width = Math.Abs(p1.X - p2.X);
        _rect.Height = Math.Abs(p1.Y - p2.Y);
    }

    protected override void OnFormClosed(FormClosedEventArgs e)
    {
        _pen.Dispose(); _g?.Dispose();
        base.OnFormClosed(e);
    }
}

關鍵技術點

  • CopyFromScreen:高效螢幕像素複製,支援多螢幕(範例取主螢幕)。
  • 無框最大化視窗:覆蓋全螢幕,無標題列干擾。
  • 手動雙緩衝:在記憶體 Bitmap 繪製後一次 DrawImageUnscaled 到螢幕,避免閃爍。
  • 剪貼簿互通:Clipboard.SetImage 直接支援 Bitmap,貼上即可使用。

已知限制

  • 單螢幕支援,多螢幕需處理虛擬螢幕座標。
  • 高 DPI 縮放下座標需轉換(SetProcessDpiAwareness)。
  • 無放大鏡、標註、儲存檔案等進階功能。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved