使用dshow獲取屏幕截圖 不包含鼠標

正常錄製屏幕可以使用ffmpeg直接獲取屏幕圖像:

使用ffmpeg獲取屏幕圖像


但是 現在有時希望獲取的屏幕截圖上不要有鼠標,研究了好久 發現ffmpeg似乎做不到。

查了好久發現可以直接使用dshow來獲取:

代碼如下:


#ifndef GETSCREEN_H
#define GETSCREEN_H

#include 
#include 
#include 
#include   //定義成一個可變參數列表的指針

typedef unsigned char uint8_t;

/**
 * @brief GetBitmapFromScreen 獲取屏幕截圖
 * @param w 返回屏幕寬度
 * @param h 返回高度
 * @return 返回rgb數據
 */
uint8_t* GetBitmapFromScreen(int *w, int *h);
int SaveBitmapToFile(BITMAP *bitmap, LPSTR lpFileName,char *lpBuf);


#endif // GETSCREEN_H




.cpp文件

需要加上這幾個庫
//LIBS += -lddraw -lgdi32 -lole32 -loleaut32

#include 
#include 
#include 
#include   //定義成一個可變參數列表的指針

int SaveBitmapToFile(BITMAP *bitmap, LPSTR lpFileName,char *lpBuf)
{
   DWORD dwWritten;
   BITMAPFILEHEADER   bmfHdr;
   BITMAPINFOHEADER   bi;
   HANDLE          fh=NULL;
   bi.biSize = sizeof(BITMAPINFOHEADER);
   bi.biWidth= bitmap->bmWidth;
   bi.biHeight = bitmap->bmHeight;
   bi.biPlanes = 1;
   bi.biBitCount         =bitmap->bmBitsPixel*8;
   bi.biCompression      = BI_RGB;
   bi.biSizeImage        = 0;
   bi.biXPelsPerMeter     = 0;
   bi.biYPelsPerMeter     = 0;
   bi.biClrUsed         = 0;
   bi.biClrImportant      = 0;


   //將char* 轉成wchar_t*的實現函數如下:
   char *CStr = lpFileName;
   size_t len = strlen(CStr) + 1;
   size_t converted = 0;
   wchar_t *WStr;
   WStr=(wchar_t*)malloc(len*sizeof(wchar_t));
   mbstowcs_s(&converted, WStr, len, CStr, _TRUNCATE);

   fh = CreateFile(WStr, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
   if (fh == INVALID_HANDLE_VALUE)
      return FALSE;
   bmfHdr.bfType = 0x4D42;  // "BM"
   bmfHdr.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+bitmap->bmWidth*bitmap->bmHeight*bitmap->bmBitsPixel;
   bmfHdr.bfReserved1 = 0;
   bmfHdr.bfReserved2 = 0;
   bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
   WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
   WriteFile(fh, (char *)&bi,sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
   WriteFile(fh, (char *)lpBuf,bitmap->bmWidth*bitmap->bmHeight*bitmap->bmBitsPixel, &dwWritten, NULL);
   FlushFileBuffers(fh);
   CloseHandle(fh);
   return true;
}

uint8_t* GetBitmapFromScreen(int *w, int*h)
{
 char *lpBuf;
 HBITMAP hBitmap,hOld ;
 HDC hDC,hcDC;
 BITMAP bb;BITMAPINFO b;
 HANDLE hp,fh=NULL;

 DWORD dwX,dwY;
 //***************
 dwX=GetSystemMetrics(SM_CXSCREEN);
 dwY=GetSystemMetrics(SM_CYSCREEN);

 *w = dwX;
 *h = dwY;

 hDC=GetDC(NULL);
 hcDC=CreateCompatibleDC(hDC);
 hBitmap=CreateCompatibleBitmap(hDC,dwX,dwY);
 hOld=(HBITMAP)SelectObject(hcDC,hBitmap);
 BitBlt(hcDC,0, 0,dwX,dwY, hDC, 0, 0, SRCCOPY);
 bb.bmWidth=dwX;
 bb.bmHeight =dwY;
 bb.bmPlanes = 1;
 bb.bmWidthBytes=bb.bmWidth*3;
 bb.bmBitsPixel=3;
 bb.bmType=0;
 b.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 b.bmiHeader.biWidth=dwX;
 b.bmiHeader.biHeight =dwY;
 b.bmiHeader.biPlanes = 1;
 b.bmiHeader.biBitCount        =3*8;
 b.bmiHeader.biCompression      = BI_RGB;
 b.bmiHeader.biSizeImage        = 0;
 b.bmiHeader.biXPelsPerMeter     = 0;
 b.bmiHeader.biYPelsPerMeter     = 0;
 b.bmiHeader.biClrUsed         = 0;
 b.bmiHeader.biClrImportant      = 0;
 b.bmiColors[0].rgbBlue=8;
 b.bmiColors[0].rgbGreen=8;
 b.bmiColors[0].rgbRed=8;
 b.bmiColors[0].rgbReserved=0;
 hp=GetProcessHeap();
 lpBuf=(char *)HeapAlloc(hp,HEAP_ZERO_MEMORY,bb.bmHeight*bb.bmWidth*4);
 GetDIBits(hcDC,hBitmap,0,dwY,lpBuf,&b,DIB_RGB_COLORS);

// char *lpFileName = "out.bmp";
// SaveBitmapToFile(&bb,lpFileName,lpBuf); //將截圖保存成bmp圖片

 BYTE *rgbData = (unsigned char *)malloc(dwX * dwY * 3);
 memset(rgbData,0,dwX * dwY * 3);
 memcpy(rgbData,lpBuf,dwX * dwY * 3);

 ReleaseDC(NULL,hDC);
 DeleteDC(hcDC);
 DeleteObject(hBitmap);
 DeleteObject(hOld);
 HeapFree(hp,0,lpBuf);

 return rgbData;
}


//調用方法
int main()
{
   int w;
   int h;
    unsigned char* rgbData = GetBitmapFromScreen(&w,&h);
}


empty



關於獲取到的rgb數據如何轉換成Yuv請查看另一篇文章。

發佈了43 篇原創文章 · 獲贊 46 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章