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 }

 


免責聲明!

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



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