如何快速截屏?(目前的耗时大约为15ms,希望能控制在5ms以内)

kzby2003 2012-08-23 05:53:47
以下是我写的一段截屏代码,截取的图片要求是位图的格式,现在截图时间大约要15ms,希望能进一步提高执行效率,最好能把耗时控制在5ms以内,不知道可不可以,谢谢。

CDC dc;
CDC *pDC = &dc;//屏幕DC

HWND hwnd = ::GetForegroundWindow();
HDC activeDC = ::GetWindowDC(hwnd); //获得当前活动窗口的hDC

pDC->Attach(activeDC);//获取当前活动窗口的DC
RECT rect;
::GetWindowRect(hwnd,&rect);//得到活动窗口的大小
UINT Width = rect.right - rect.left;

UINT Height = rect.bottom - rect.top;

CDC memDC;//内存DC

memDC.CreateCompatibleDC(pDC);

CBitmap memBitmap, *oldmemBitmap;//建立和屏幕兼容的bitmap

memBitmap.CreateCompatibleBitmap(pDC, Width, Height);

oldmemBitmap = memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC

memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY);//复制屏幕图像到内存DC

BITMAP bmp;

memBitmap.GetBitmap(&bmp);//获得位图信息

BITMAPINFOHEADER bih = {0};//位图信息头

bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小

bih.biCompression = BI_RGB;

bih.biHeight = bmp.bmHeight;//高度

bih.biPlanes = 1;

bih.biSize = sizeof(BITMAPINFOHEADER);

bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//图像数据大小

bih.biWidth = bmp.bmWidth;//宽度

BITMAPFILEHEADER bfh = {0};//位图文件头

bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量

bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;//文件总的大小

bfh.bfType = (WORD)0x4d42;

BYTE * up = new BYTE[bmp.bmWidthBytes * bmp.bmHeight];//申请内存保存位图数据

GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Height, up,

(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据
//以下是保存图片的代码,略
...全文
946 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
FISH_LJZ 2015-02-03
  • 打赏
  • 举报
回复
引用 7 楼 wangjia184 的回复:
好久不来 发现CSDN的水平下滑严重啊 最快速的截屏方式应该是 镜像驱动, 很多远程桌面共享 软件都采用这种方式 就用VNC里面的吧,很好很方便 http://www.uvnc.com/features/driver.html
同问 大哥 这个该如何使用啊?
luofl_ 2012-08-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

好久不来 发现CSDN的水平下滑严重啊

最快速的截屏方式应该是 镜像驱动, 很多远程桌面共享 软件都采用这种方式

就用VNC里面的吧,很好很方便
http://www.uvnc.com/features/driver.html
[/Quote]
怎么用啊?
CodeProject-Jerry 2012-08-23
  • 打赏
  • 举报
回复
好久不来 发现CSDN的水平下滑严重啊

最快速的截屏方式应该是 镜像驱动, 很多远程桌面共享 软件都采用这种方式

就用VNC里面的吧,很好很方便
http://www.uvnc.com/features/driver.html

stjay 2012-08-23
  • 打赏
  • 举报
回复
再怎么优化代码都没用的
最快的就是驱动方式,如Mirror driver
其次DirectX
GDI较慢
xiaohuh421 2012-08-23
  • 打赏
  • 举报
回复
使用CDC截图估计效率也差不多这样了,当然,跟PC机性能也有一定关系哈.
使用更底层的技术,应该可以更快,比如DirectX
看不见的裂痕 2012-08-23
  • 打赏
  • 举报
回复
3.memBitmap.CreateCompatibleBitmap(pDC, Width, Height);

oldmemBitmap = memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC

这里也可以放到全局,反正都不变的,开局的时候初始化一次就可以了,因为你每次图片大小都一样的,而且MEM每次都选中这个的
看不见的裂痕 2012-08-23
  • 打赏
  • 举报
回复
我来说点实质的修改点

1.
CDC memDC;//内存DC 放全局变量里
memDC.CreateCompatibleDC(pDC); // 这个页面初始化的时候就创建,不必每次都创建。


2. BITMAPINFOHEADER bih = {0};//大部分信息都是固定的,固定的就放全局,不变的放在函数里面
smwhotjay 2012-08-23
  • 打赏
  • 举报
回复
1.执行代码多了呗.
2.还有c++类用多了. . try catch其实也会消耗吧.
3.再就是减少计算量.
4.不要new delete. 这个最耗! 而且时间长短不稳定!
Eleven 2012-08-23
  • 打赏
  • 举报
回复
BOOL SaveHwndToBmpFile(HWND hWnd, LPCTSTR lpszPath)
{
HWND hDesktop = ::GetDesktopWindow();
ASSERT(hDesktop);
if(NULL == hWnd)
{
hWnd = hDesktop;
}
RECT rect;
::GetWindowRect(hWnd, &rect);

int nWidht = rect.right - rect.left;
int nHeight = rect.bottom - rect.top;

HDC hSrcDC = ::GetWindowDC(hWnd);
ASSERT(hSrcDC);
HDC hMemDC = ::CreateCompatibleDC(hSrcDC);
ASSERT(hMemDC);
HBITMAP hBitmap = ::CreateCompatibleBitmap(hSrcDC, nWidht, nHeight);
ASSERT(hBitmap);
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemDC, hBitmap);
::BitBlt(hMemDC, 0, 0, nWidht, nHeight, hSrcDC, 0, 0, SRCCOPY);

BITMAP bitmap = {0};
::GetObject(hBitmap, sizeof(BITMAP), &bitmap);
BITMAPINFOHEADER bi = {0};
BITMAPFILEHEADER bf = {0};

CONST int nBitCount = 24;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bitmap.bmWidth;
bi.biHeight = bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = nBitCount;
bi.biCompression = BI_RGB;
DWORD dwSize = ((bitmap.bmWidth * nBitCount + 31) / 32) * 4 * bitmap.bmHeight;

HANDLE hDib = GlobalAlloc(GHND, dwSize + sizeof(BITMAPINFOHEADER));
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;

::GetDIBits(hMemDC, hBitmap, 0, bitmap.bmHeight, (BYTE*)lpbi + sizeof(BITMAPINFOHEADER), (BITMAPINFO*)lpbi, DIB_RGB_COLORS);

try
{
CFile file;
file.Open(lpszPath, CFile::modeCreate | CFile::modeWrite);
bf.bfType = 0x4d42;
dwSize += sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bf.bfSize = dwSize;
bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

file.Write((BYTE*)&bf, sizeof(BITMAPFILEHEADER));
file.Write((BYTE*)lpbi, dwSize);
file.Close();
}
catch(CFileException* e)
{
e->ReportError();
e->Delete();
}

GlobalUnlock(hDib);
GlobalFree(hDib);

::SelectObject(hMemDC, hOldBitmap);
::DeleteObject(hBitmap);
::DeleteDC(hMemDC);
::ReleaseDC(hWnd, hSrcDC);

return TRUE;
}


// 调用方法
HWND hWnd = GetSafeHwnd();
if(hWnd)
{
DWORD dwStart = GetTickCount();
SaveHwndToBmpFile(hWnd, _T("E://12.bmp"));
DWORD dwValue = GetTickCount() - dwStart;
CString strText(_T(""));
strText.Format(_T("%d ms"), dwValue);
AfxMessageBox(strText);
}

19,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧