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

C# 動態截圖實作:全螢幕擷取、區域選取與表單間資料傳遞

     編輯:關於C語言

動態截圖工具核心技術解析

實作類似 QQ 截圖功能:先擷取全螢幕到全螢幕覆蓋表單,使用者在覆蓋層框選區域,再將選取影像傳回主表單。關鍵技術包含 GDI 截圖、表單間資料傳遞(委派/建構子)、資源釋放。

主要流程

  1. 主表單隱藏,呼叫 GetAllScreen() 截取全螢幕位圖。
  2. 建立截圖表單 CaptureScreen,建構子傳入全螢幕位圖與主表單參考。
  3. 截圖表單顯示全螢幕影像,滑鼠事件繪製選取框與尺寸提示。
  4. 雙擊確認時,呼叫 GetPartScreen() 截取選取區域位圖。
  5. 透過委派或公開方法將位圖傳回主表單顯示。
  6. 主表單重寫 OnPaint 確保影像正確重繪。

關鍵程式碼片段

全螢幕截圖 (GDI BitBlt)

[DllImport("gdi32.dll")]
private static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);

private Bitmap GetAllScreen()
{
    Graphics gScreen = Graphics.FromHwnd(IntPtr.Zero);
    Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, gScreen);
    Graphics gBmp = Graphics.FromImage(bmp);
    IntPtr hdcScreen = gScreen.GetHdc();
    IntPtr hdcBmp = gBmp.GetHdc();
    BitBlt(hdcBmp, 0, 0, bmp.Width, bmp.Height, hdcScreen, 0, 0, 0x00CC0020); // SRCCOPY
    gBmp.ReleaseHdc(hdcBmp);
    gScreen.ReleaseHdc(hdcScreen);
    gBmp.Dispose();
    gScreen.Dispose();
    return bmp;
}

區域截圖

private Bitmap GetPartScreen(Point p1, Point p2)
{
    int x = Math.Min(p1.X, p2.X);
    int y = Math.Min(p1.Y, p2.Y);
    int w = Math.Abs(p1.X - p2.X);
    int h = Math.Abs(p1.Y - p2.Y);
    if (w == 0 || h == 0) return null;

    IntPtr hdcScreen = CreateDC("DISPLAY", null, null, IntPtr.Zero);
    IntPtr hdcMem = CreateCompatibleDC(hdcScreen);
    IntPtr hBitmap = CreateCompatibleBitmap(hdcScreen, w, h);
    IntPtr hOld = SelectObject(hdcMem, hBitmap);
    BitBlt(hdcMem, 0, 0, w, h, hdcScreen, x, y, 0x00CC0020);
    SelectObject(hdcMem, hOld);
    DeleteDC(hdcScreen);
    DeleteDC(hdcMem);
    return Bitmap.FromHbitmap(hBitmap);
}

// 所需 API
[DllImport("gdi32.dll")] private static extern IntPtr CreateDC(string driver, string device, string output, IntPtr init);
[DllImport("gdi32.dll")] private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")] private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int w, int h);
[DllImport("gdi32.dll")] private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("gdi32.dll")] private static extern int DeleteDC(IntPtr hdc);

表單間傳遞:委派模式

// 主表單定義委派
public delegate void ImageReceivedHandler(Bitmap img);
public event ImageReceivedHandler OnImageReceived;

// 截圖表單建構子接收委派
public CaptureScreen(Bitmap fullScreen, ImageReceivedHandler callback)
{
    InitializeComponent();
    _fullScreen = fullScreen;
    _callback = callback;
}

// 雙擊確認時觸發
private void picScreen_DoubleClick(object sender, EventArgs e)
{
    Bitmap part = GetPartScreen(_startPoint, _endPoint);
    _callback?.Invoke(part);
    this.Close();
}

常見坑點與解決

  • 影像不更新:主表單隱藏/顯示導致 PictureBox 未重繪 → 覆寫 OnPaint 強制更新。
  • GDI 物件洩漏:所有 GetHdc、CreateDC、SelectObject 必須配對 ReleaseHdc/DeleteDC/SelectObject 還原。
  • 多螢幕支援:使用 Screen.AllScreens 計算虛擬桌面範圍,而非單一 PrimaryScreen。

進階擴充: 加入標註工具、直接存檔、上傳雲端、多螢幕合成截圖。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved