C++ wingdi实现屏幕截图
直接获取当前屏幕bitmap保存成bmp图像, 使用的接口都可以在msdn查找到资料
内容参考 : https://docs.microsoft.com/en-us/windows/win32/gdi/capturing-an-image
https://www.cnblogs.com/cdh49/p/3558353.html
使用的gdi接口有很多参数还没搞很透彻, 有机会再补充
下面是代码, 如有疏漏, 欢迎指正
1 #include <Windows.h> 2 #include <stdio.h> 3 #include <tchar.h> 4 5 #pragma warning(disable:4996) 6 7 #define TAG_DEV_PLAS 1 8 #define BITS_PER_PIX 32 9 #define NO_COLOR_TAB 0 10 #define UNCMP_RGB 0 11 #define H_RESOL_0 0 12 #define V_RESOL_0 0 13 #define ALL_COLOR 0 14 15 #define MUST_ZERO 0 16 #define TYPE_BMP 0x4D42 17 18 #define FILE_HEAD sizeof(BITMAPFILEHEADER) 19 #define INFO_HEAD sizeof(BITMAPINFOHEADER) 20 #define HEAD_SIZE sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) 21 22 bool ScreenShot(const char* szSavePath) 23 { 24 //显示器屏幕 25 HDC hCurrScreen = GetDC(NULL); 26 27 //创建一个兼容的DC,在内存中表示当前位图的上下文 28 HDC hCmpDC = CreateCompatibleDC(hCurrScreen); 29 30 //宽高 31 int iScreenWidth = GetDeviceCaps(hCurrScreen, HORZRES); 32 int iScreenHeight = GetDeviceCaps(hCurrScreen, VERTRES); 33 34 //当前屏幕位图 35 HBITMAP hBmp = CreateCompatibleBitmap(hCurrScreen, iScreenWidth, iScreenHeight); 36 37 //用当前位图句柄表示内存中屏幕位图上下文 38 SelectObject(hCmpDC,hBmp); 39 40 //将当前屏幕图像复制到内存中 41 BOOL ret = BitBlt(hCmpDC, 0, 0, iScreenWidth, iScreenHeight, hCurrScreen, 0, 0, SRCCOPY); 42 43 //BMP图像信息头 44 BITMAPINFOHEADER hBmpInfo; 45 hBmpInfo.biSize = INFO_HEAD; 46 hBmpInfo.biWidth = iScreenWidth; 47 hBmpInfo.biHeight = iScreenHeight; 48 hBmpInfo.biPlanes = TAG_DEV_PLAS; 49 hBmpInfo.biClrUsed = NO_COLOR_TAB; 50 hBmpInfo.biBitCount = BITS_PER_PIX; 51 hBmpInfo.biSizeImage = UNCMP_RGB; 52 hBmpInfo.biCompression = BI_RGB; 53 hBmpInfo.biClrImportant = ALL_COLOR; 54 hBmpInfo.biXPelsPerMeter = H_RESOL_0; 55 hBmpInfo.biYPelsPerMeter = V_RESOL_0; 56 57 /* * * * * * * * * * * * * * * * * * * * 58 * Windows按4字节分配内存 59 * 首先计算每行所需要的bit数,并按4字节对齐 60 * 对齐后的数据乘4,从DWORD转为BYTE 61 * 每行实际所占BYTE乘图像列数得到数据源大小 62 * * * * * * * * * * * * * * * * * * * */ 63 DWORD dwSrcSize = ((iScreenWidth * hBmpInfo.biBitCount + 31) / 32) * 4 * iScreenHeight; 64 65 //截图总大小 66 DWORD dwPicSize = HEAD_SIZE + dwSrcSize; 67 68 //BMP图像文件头 69 BITMAPFILEHEADER hBmpFile; 70 hBmpFile.bfSize = dwPicSize; 71 hBmpFile.bfType = TYPE_BMP; 72 hBmpFile.bfOffBits = HEAD_SIZE; 73 hBmpFile.bfReserved1 = MUST_ZERO; 74 hBmpFile.bfReserved2 = MUST_ZERO; 75 76 //BMP图像数据源 77 char *bmpSrc = new char[dwSrcSize]; 78 ZeroMemory(bmpSrc, dwSrcSize); 79 80 //检索指定的兼容位图中的所有位元数据 81 //并复制到指定格式的设备无关位图的缓存中 82 GetDIBits(hCmpDC, hBmp, 0, (UINT)iScreenHeight, bmpSrc, (BITMAPINFO*)&hBmpInfo, DIB_RGB_COLORS); 83 84 //汇总所有数据信息 85 char *szBmp = new char[dwPicSize]; 86 ZeroMemory(szBmp, dwPicSize); 87 memcpy(szBmp, (void*)&hBmpFile, FILE_HEAD); 88 memcpy(szBmp + FILE_HEAD, (void*)&hBmpInfo, INFO_HEAD); 89 memcpy(szBmp + HEAD_SIZE, bmpSrc, dwSrcSize); 90 91 //保存BMP图像 92 FILE *hFile = fopen(szSavePath, "wb+"); 93 if (nullptr != hFile) 94 { 95 size_t count = fwrite(szBmp, 1, dwPicSize, hFile); 96 fclose(hFile); 97 } 98 99 //释放资源 100 DeleteObject(hBmp); 101 DeleteObject(hCmpDC); 102 ReleaseDC(NULL, hCurrScreen); 103 delete[] szBmp; 104 delete[] bmpSrc; 105 szBmp = nullptr; 106 bmpSrc = nullptr; 107 return true; 108 }