場景:
採集屏幕,並將採集的屏幕數據 轉成YUV數據發送出去
分析:
要實現這一需求, 需要有這幾方面參數
HBITMAP capture_bitmap_ 位圖
HWND capture_hwnd_ 屏幕
char* capture_data 屏幕數據
capture_width 屏幕寬
capture_height 屏幕高
實現:
核心代碼是創建位圖 繪製位圖
1) 初始化位圖
InitHBitmap(int width, int height)
{
if (capture_width_ != width || capture_height_ != height)
{
if (capture_bitmap_)
{
DeleteObject(capture_bitmap_);
capture_bitmap_ = nullptr;
}
capture_width_ = width;
capture_height_ = height;
capture_width_ -= capture_width_ % 2;
capture_height_ -= capture_height_ % 2;
HDC hdc = ::GetDC(capture_hwnd_);
HDC hMemDC = CreateCompatibleDC(hdc);
BITMAPINFO bmi;
::ZeroMemory(&bmi, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = capture_width_;
bmi.bmiHeader.biHeight = capture_height_;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = capture_width_*capture_height_ * 4;
capture_bitmap_ = ::CreateDIBSection(hMemDC, &bmi, DIB_RGB_COLORS,
(void**)&capture_data_, NULL, 0);
DeleteDC(hMemDC);
::ReleaseDC(capture_hwnd_, hdc);
}
else if (capture_data_ != nullptr)
{
ZeroMemory(capture_data_, capture_width_*capture_height_ * 4);
}
}
2 繪製:
將屏幕繪製到位圖中
CustomFrame()
{
if (IsWindow(capture_hwnd_))
{
// 把屏幕設備描述表拷貝到內存設備描述表中
HDC w_dc = GetDC(capture_hwnd_);
if (w_dc)
{
RECT rcDlg;
if (cut_screen_)
{
rcDlg = cut_rect_;
}
else
{
if (!IsIconic(capture_hwnd_))
{
::GetClientRect(capture_hwnd_, &rcDlg);
}
else
{
ReleaseDC(capture_hwnd_, w_dc);
return;
}
}
int width = rcDlg.right - rcDlg.left;
int height = rcDlg.bottom - rcDlg.top;
InitHBitmap(width, height);
if (capture_bitmap_ == nullptr)
{
return;
}
HDC mem_dc = CreateCompatibleDC(w_dc);
HBITMAP old_hbitmap = (HBITMAP)SelectObject(mem_dc, capture_bitmap_);
//__int64 time0 = get_time_ms();
if (cut_screen_)
{
BitBlt(mem_dc, 0, 0, capture_width_, capture_height_, w_dc, cut_rect_.left, cut_rect_.top, SRCCOPY /*| CAPTUREBLT*/);
}
else
{
BitBlt(mem_dc, 0, 0, capture_width_, capture_height_, w_dc, 0, 0, SRCCOPY /*| CAPTUREBLT*/);
}
//__int64 time1 = get_time_ms();
//鼠標
if (1)
{
CURSORINFO pci;
pci.cbSize = sizeof(CURSORINFO);
GetCursorInfo(&pci);
POINT ptCursor = pci.ptScreenPos;
ICONINFO IconInfo = { 0 };
if (GetIconInfo(pci.hCursor, &IconInfo))
{
ptCursor.x -= IconInfo.xHotspot;
ptCursor.y -= IconInfo.yHotspot;
if (NULL != IconInfo.hbmMask)
DeleteObject(IconInfo.hbmMask);
if (NULL != IconInfo.hbmColor)
DeleteObject(IconInfo.hbmColor);
}
if (capture_hwnd_ != nullptr)
{
//RECT rcDlg;
//::GetWindowRect(capture_hwnd_, &rcDlg);
//ptCursor.x -= rcDlg.left;
//ptCursor.y -= rcDlg.top;
ScreenToClient(capture_hwnd_, &ptCursor);
}
if (cut_screen_)
{
ptCursor.x -= cut_rect_.left;
ptCursor.y -= cut_rect_.top;
}
DrawIconEx(mem_dc, ptCursor.x, ptCursor.y, pci.hCursor, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
}
SelectObject(mem_dc, old_hbitmap);
DeleteDC(mem_dc);
ReleaseDC(capture_hwnd_, w_dc);
//繪製位圖 ,位圖的具體數據保存在capture_data 中
}
}
}
繪製位圖 ,位圖的具體數據保存在capture_data 中,可對其進一步處理