由于使用ffmpeg gdigrab采集程序窗口效果不太好,于是又研究了一下新的窗口截图技术,该篇文章总结一下使用PrintWindow对窗口截流的心得。
1、初始化采集器
如果采集的窗口最小化,先将其显示出来,然后通过GetWindowRect获取窗口大小,PrintWindow可以截取窗口的全部区域(包括客户区域和标题区域)
int GdiCaptor::init(const std::string& deviceId, const int fps)
{
int err = ERROR_CODE_OK;
if (m_inited) {
return err;
}
do {
HWND hwnd = reinterpret_cast<HWND>(atol(deviceId.c_str()));
if (hwnd == nullptr) {
err = ERROR_CODE_PARAMS_ERROR;
break;
}
// 将最小化窗口显示出来
if (::IsIconic(hwnd)) {
::ShowWindow(hwnd, SW_SHOWNOACTIVATE);
}
RECT rect = {
};
::GetWindowRect(hwnd, &rect);
m_srcDc = ::GetWindowDC(hwnd);
m_memDc = ::CreateCompatibleDC(m_srcDc);
m_deviceId = deviceId;
m_rect = rect;
m_fps = fps;
m_pixelFmt = AV_PIX_FMT_BGRA;
m_inited = true;
} while (0);
if (err != ERROR_CODE_OK) {
LOGGER::Logger::log(LOGGER::LOG_TYPE_ERROR, "[%s] init vstream captor error: %s, last error: %lu",
__FUNCTION__, HCMDR_GET_ERROR_DESC(err), GetLastError());
cleanup();
}
return err;
}
2、开启采集
int GdiCaptor::start()
{
int err = ERROR_CODE_OK;
if (m_running)