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