C語言實現截屏


 

實現手機控制電腦執行部分功能需要獲取桌面狀態,在網上找的一段截屏代碼

 

/**
 * GDI 截屏函數
 * 參數 hwnd   要截屏的窗口句柄
 * 參數 dirPath    截圖存放目錄
 * 參數 filename 截圖名稱
 */
int CaptureImage(HWND hwnd, const char *dirPath, const char *filename)
{
    HANDLE hDIB;
    HANDLE hFile;
    DWORD dwBmpSize;
    DWORD dwSizeofDIB;
    DWORD dwBytesWritten;
    CHAR FilePath[MAX_PATH];
    HBITMAP hbmScreen = NULL;
    BITMAP bmpScreen;
    BITMAPFILEHEADER bmfHeader;
    BITMAPINFOHEADER bi;
    CHAR *lpbitmap;
    INT width = GetSystemMetrics(SM_CXSCREEN);  // 屏幕寬
    INT height = GetSystemMetrics(SM_CYSCREEN);  // 屏幕高
    HDC hdcScreen = GetDC(NULL); // 全屏幕DC
    HDC hdcMemDC = CreateCompatibleDC(hdcScreen); // 創建兼容內存DC

    if (!hdcMemDC)
    {
        DeleteObject(hbmScreen);
        DeleteObject(hdcMemDC);
        ReleaseDC(NULL, hdcScreen);
        return 0;
    }

    // 通過窗口DC 創建一個兼容位圖
    hbmScreen = CreateCompatibleBitmap(hdcScreen, width, height);
    if (!hbmScreen)
    {
        DeleteObject(hbmScreen);
        DeleteObject(hdcMemDC);
        ReleaseDC(NULL, hdcScreen);
        return 0;
    }
    // 將位圖塊傳送到我們兼容的內存DC中
    SelectObject(hdcMemDC, hbmScreen);
    if (!BitBlt(
        hdcMemDC,    // 目的DC
        0, 0,        // 目的DC的 x,y 坐標
        width, height, // 目的 DC 的寬高
        hdcScreen,   // 來源DC
        0, 0,        // 來源DC的 x,y 坐標
        SRCCOPY))    // 粘貼方式
    {
        DeleteObject(hbmScreen);
        DeleteObject(hdcMemDC);
        ReleaseDC(NULL, hdcScreen);
        return 0;
    }

    // 獲取位圖信息並存放在 bmpScreen 中
    GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);

    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bmpScreen.bmWidth;
    bi.biHeight = bmpScreen.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = 32;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;

    // 在 32-bit Windows 系統上, GlobalAlloc 和 LocalAlloc 是由 HeapAlloc 封裝來的
    // handle 指向進程默認的堆. 所以開銷比 HeapAlloc 要大
    hDIB = GlobalAlloc(GHND, dwBmpSize);
    lpbitmap = (char *)GlobalLock(hDIB);

    // 獲取兼容位圖的位並且拷貝結果到一個 lpbitmap 中.
    GetDIBits(
        hdcScreen,  // 設備環境句柄
        hbmScreen,  // 位圖句柄
        0,          // 指定檢索的第一個掃描線
        (UINT)bmpScreen.bmHeight, // 指定檢索的掃描線數
        lpbitmap,   // 指向用來檢索位圖數據的緩沖區的指針
        (BITMAPINFO *)&bi, // 該結構體保存位圖的數據格式
        DIB_RGB_COLORS // 顏色表由紅、綠、藍(RGB)三個直接值構成
    );


    wsprintf(FilePath, "%s\%s.jpg", dirPath, filename);

    // 創建一個文件來保存文件截圖
    hFile = CreateFile(
        FilePath,
        GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    // 將 圖片頭(headers)的大小, 加上位圖的大小來獲得整個文件的大小
    dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    // 設置 Offset 偏移至位圖的位(bitmap bits)實際開始的地方
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);

    // 文件大小
    bmfHeader.bfSize = dwSizeofDIB;

    // 位圖的 bfType 必須是字符串 "BM"
    bmfHeader.bfType = 0x4D42; //BM

    dwBytesWritten = 0;
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);

    // 解鎖堆內存並釋放
    GlobalUnlock(hDIB);
    GlobalFree(hDIB);

    // 關閉文件句柄
    CloseHandle(hFile);

    // 清理資源
    DeleteObject(hbmScreen);
    DeleteObject(hdcMemDC);
    ReleaseDC(NULL, hdcScreen);

    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM