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

C# 螢幕截圖完整教學:呼叫 GDI API 實作高效螢幕擷取

     編輯:關於C語言

前言

C# 擁有豐富的類別庫,但涉及底層視窗繪圖、螢幕擷取等作業時,仍需透過 P/Invoke 呼叫 Windows API。本文詳細說明如何使用 GDI32.dll 的 BitBlt 函數,結合 System.Drawing 命名空間,實作一個完整的螢幕截圖工具。

開發環境與前置需求

  • 作業系統:Windows 2000 Server 以上
  • 框架:.NET Framework SDK(Beta 2 或正式版)
  • 命名空間:System.Runtime.InteropServices、System.Drawing、System.Windows.Forms

核心 API 宣告

BitBlt 為 GDI 核心位元區塊傳輸函數,簽名如下:

[DllImport("gdi32.dll")]
private static extern bool BitBlt(
    IntPtr hdcDest,   // 目標裝置內容控制代碼
    int nXDest,       // 目標矩形左上角 X
    int nYDest,       // 目標矩形左上角 Y
    int nWidth,       // 寬度
    int nHeight,      // 高度
    IntPtr hdcSrc,    // 來源裝置內容控制代碼
    int nXSrc,        // 來源矩形左上角 X
    int nYSrc,        // 來源矩形左上角 Y
    int dwRop         // 光柵操作代碼(SRCCOPY = 13369376)
);

實作步驟詳解

1. 取得螢幕範圍

Rectangle rect = Screen.GetWorkingArea(this);
int width = rect.Width;
int height = rect.Height;

2. 建立螢幕 Graphics 與目標 Bitmap

Graphics gScreen = this.CreateGraphics();
Image screenImage = new Bitmap(width, height, gScreen);
Graphics gBitmap = Graphics.FromImage(screenImage);

3. 取得雙方裝置內容控制代碼 (HDC)

IntPtr hdcSrc = gScreen.GetHdc();   // 螢幕 DC
IntPtr hdcDest = gBitmap.GetHdc();  // Bitmap DC

4. 執行 BitBlt 複製像素資料

BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, 13369376); // SRCCOPY

5. 釋放 DC 資源

gScreen.ReleaseHdc(hdcSrc);
gBitmap.ReleaseHdc(hdcDest);

6. 儲存影像檔

screenImage.Save(@"C:\Capture.jpg", ImageFormat.Jpeg);
// 亦可改為 ImageFormat.Bmp、ImageFormat.Gif、ImageFormat.Png 等

完整程式碼範例 (Capture.cs)

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public class ScreenCaptureForm : Form
{
    private Button btnCapture;

    [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);

    public ScreenCaptureForm()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        btnCapture = new Button
        {
            Location = new Point(64, 40),
            Size = new Size(80, 32),
            Text = "擷取螢幕",
            TabIndex = 0
        };
        btnCapture.Click += BtnCapture_Click;

        ClientSize = new Size(216, 125);
        Controls.Add(btnCapture);
        Text = "C# 螢幕截圖示範";
        MaximizeBox = false;
        MinimizeBox = false;
    }

    private void BtnCapture_Click(object sender, EventArgs e)
    {
        Rectangle rect = Screen.GetWorkingArea(this);
        using (Graphics gScreen = this.CreateGraphics())
        using (Image img = new Bitmap(rect.Width, rect.Height, gScreen))
        using (Graphics gBitmap = Graphics.FromImage(img))
        {
            IntPtr hdcSrc = gScreen.GetHdc();
            IntPtr hdcDest = gBitmap.GetHdc();
            try
            {
                BitBlt(hdcDest, 0, 0, rect.Width, rect.Height, hdcSrc, 0, 0, 13369376);
            }
            finally
            {
                gScreen.ReleaseHdc(hdcSrc);
                gBitmap.ReleaseHdc(hdcDest);
            }

            string path = @"C:\Capture.jpg";
            img.Save(path, ImageFormat.Jpeg);
            MessageBox.Show($"螢幕已儲存至 {path}");
        }
    }

    [STAThread]
    static void Main() => Application.Run(new ScreenCaptureForm());
}

進階應用與注意事項

  • 多螢幕支援:使用 Screen.AllScreens 列舉所有螢幕,計算虛擬桌面總範圍。
  • 高 DPI 相容:在 .NET 4.7+ 設定 SetProcessDpiAwareness 避免縮放模糊。
  • 效能優化:若需高頻率截圖(如錄製影片),建議改用 Desktop Duplication API (Windows 8+) 或 DirectX。
  • 權限問題:寫入 C 根目錄需管理員權限,實務上應儲存至 Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)。

總結

透過 BitBlt 結合 GDI+,C# 即可輕鬆實作螢幕截圖。關鍵在於正確管理 HDC 生命週期(GetHdc/ReleaseHdc 配對),並善用 using 區塊確保資源釋放。此技術同樣適用於視窗截圖、遊戲畫面擷取等進階場景。

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