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 }

 

posted @ 2020-04-28 19:25  public_tsing  阅读(1495)  评论(0编辑  收藏  举报