首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

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

2012-10-07 
如何快速截屏?(目前的耗时大约为15ms,希望能控制在5ms以内)以下是我写的一段截屏代码,截取的图片要求是位

如何快速截屏?(目前的耗时大约为15ms,希望能控制在5ms以内)
以下是我写的一段截屏代码,截取的图片要求是位图的格式,现在截图时间大约要15ms,希望能进一步提高执行效率,最好能把耗时控制在5ms以内,不知道可不可以,谢谢。

C/C++ code
        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);//获取位图数据        //以下是保存图片的代码,略


[解决办法]
C/C++ code
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);    } 


[解决办法]
我来说点实质的修改点

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


2. BITMAPINFOHEADER bih = {0};//大部分信息都是固定的,固定的就放全局,不变的放在函数里面
[解决办法]
3.memBitmap.CreateCompatibleBitmap(pDC, Width, Height);

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

这里也可以放到全局,反正都不变的,开局的时候初始化一次就可以了,因为你每次图片大小都一样的,而且MEM每次都选中这个的
[解决办法]
好久不来 发现CSDN的水平下滑严重啊

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

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

热点排行