void WINAPI CaptureScreenIntoFile() { BITMAPFILEHEADER bfHeader; BITMAPINFOHEADER biHeader; HGDIOBJ hTempBitmap; HBITMAP hBitmap; BITMAP bAllDesktops; HDC hDC, hMemDC; LONG lWidth, lHeight; ZeroMemory(&bfHeader, sizeof(BITMAPFILEHEADER)); ZeroMemory(&biHeader, sizeof(BITMAPFILEHEADER)); ZeroMemory(&bAllDesktops, sizeof(BITMAP)); hDC = GetDC(NULL); hTempBitmap = GetCurrentObject(hDC, OBJ_BITMAP); GetObjectW(hTempBitmap, sizeof(BITMAP), &bAllDesktops); lWidth = bAllDesktops.bmWidth; lHeight = bAllDesktops.bmHeight; DeleteObject(hTempBitmap); bfHeader.bfType = (WORD)('B' | ('M' << 8)); bfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); biHeader.biSize = sizeof(BITMAPINFOHEADER); biHeader.biBitCount = 24; biHeader.biCompression = BI_RGB; biHeader.biPlanes = 1; biHeader.biWidth = lWidth; biHeader.biHeight = lHeight; biHeader.biSizeImage = 0; DWORD screen_bytes_size = (((24 * lWidth + 31) & ~31) / 8) * lHeight; hMemDC = CreateCompatibleDC(hDC); HBITMAP hbmScreen = CreateCompatibleBitmap(hDC, lWidth, lHeight); SelectObject(hMemDC, hbmScreen); int x = GetSystemMetrics(SM_XVIRTUALSCREEN); int y = GetSystemMetrics(SM_YVIRTUALSCREEN); BitBlt(hMemDC, 0, 0, lWidth, lHeight, hDC, x, y, SRCCOPY); HANDLE hDIB = GlobalAlloc(GHND, screen_bytes_size); char *lpbitmap = (char *)GlobalLock(hDIB); GetDIBits(hDC, hbmScreen, 0, (UINT)lHeight, lpbitmap, (BITMAPINFO *)&biHeader, DIB_RGB_COLORS); HANDLE hFile = CreateFile("12.bmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // Add the size of the headers to the size of the bitmap to get the total file size DWORD dwSizeofDIB = screen_bytes_size + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); bfHeader.bfSize = dwSizeofDIB; DWORD dwBytesWritten = 0; WriteFile(hFile, (LPSTR)&bfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); WriteFile(hFile, (LPSTR)&biHeader, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); WriteFile(hFile, (LPSTR)lpbitmap, screen_bytes_size, &dwBytesWritten, NULL); DeleteDC(hMemDC); ReleaseDC(NULL, hDC); DeleteObject(hbmScreen); }
更新:
如果我们想把图形的信息存放到数组里面,则可以使用下面的代码。
#include <Windows.h> #include <algorithm> int main() { BITMAPFILEHEADER bfHeader; BITMAPINFOHEADER biHeader; BITMAPINFO bInfo; HGDIOBJ hTempBitmap; HBITMAP hBitmap; BITMAP bAllDesktops; HDC hDC, hMemDC; LONG lWidth, lHeight; BYTE* sb = NULL; DWORD screen_bytes_size = 0; ZeroMemory(&bfHeader, sizeof(BITMAPFILEHEADER)); ZeroMemory(&biHeader, sizeof(BITMAPFILEHEADER)); ZeroMemory(&bInfo, sizeof(BITMAPINFO)); ZeroMemory(&bAllDesktops, sizeof(BITMAP)); hDC = GetDC(NULL); hTempBitmap = GetCurrentObject(hDC, OBJ_BITMAP); GetObjectW(hTempBitmap, sizeof(BITMAP), &bAllDesktops); lWidth = bAllDesktops.bmWidth; lHeight = bAllDesktops.bmHeight; DeleteObject(hTempBitmap); bfHeader.bfType = (WORD)('B' | ('M' << 8)); bfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); biHeader.biSize = sizeof(BITMAPINFOHEADER); biHeader.biBitCount = 24; biHeader.biCompression = BI_RGB; biHeader.biPlanes = 1; biHeader.biWidth = lWidth; biHeader.biHeight = lHeight; bInfo.bmiHeader = biHeader; screen_bytes_size = (((24 * lWidth + 31) & ~31) / 8) * lHeight; hMemDC = CreateCompatibleDC(hDC); hBitmap = CreateDIBSection(hDC, &bInfo, DIB_RGB_COLORS, (VOID**)&sb, NULL, 0); SelectObject(hMemDC, hBitmap); int x = GetSystemMetrics(SM_XVIRTUALSCREEN); int y = GetSystemMetrics(SM_YVIRTUALSCREEN); BitBlt(hMemDC, 0, 0, lWidth, lHeight, hDC, x, y, SRCCOPY); // Need to also copy bfHeader & biHeader bytes somehow... BYTE *screen_bytes = new BYTE[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + screen_bytes_size]; int size = sizeof(BITMAPFILEHEADER); std::copy(&bfHeader, &bfHeader + 1 , (BITMAPFILEHEADER*)screen_bytes); //&bfHeader + 1是指偏移一个BITMAPFILEHEADER结构体大小=》14 std::copy(&biHeader, &biHeader + 1, (BITMAPINFOHEADER*)(screen_bytes + sizeof(BITMAPFILEHEADER))); std::copy(sb, sb + screen_bytes_size, screen_bytes + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)); // std::copy(sb, sb + screen_bytes_size, screen_bytes); DeleteDC(hMemDC); ReleaseDC(NULL, hDC); DeleteObject(hBitmap); return 0; }
链接: How do I get the byte representation of a BITMAPFILEHEADER and BITMAPINFOHEADER?