正常錄製屏幕可以使用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請查看另一篇文章。