屏幕採集 處理

 

場景:

        採集屏幕,並將採集的屏幕數據 轉成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 中,可對其進一步處理

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章