我將創建某種「遠程桌面」應用程序,將屏幕內容通過套接字流式傳輸到連接的客戶端。提高屏幕捕獲性能
爲了拍攝截圖,我想出了以下一段代碼,這是我在這裏和那裏看到的一個修改過的示例。
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int _tmain(int argc, _TCHAR * argv[])
{
int ScreenX = 0;
int ScreenY = 0;
BYTE* ScreenData = 0;
HDC hScreen = GetDC(GetDesktopWindow());
ScreenX = GetDeviceCaps(hScreen, HORZRES);
ScreenY = GetDeviceCaps(hScreen, VERTRES);
ScreenData = (BYTE*)calloc(4 * ScreenX * ScreenY, sizeof(BYTE));
BITMAPINFOHEADER bmi = {0};
bmi.biSize = sizeof(BITMAPINFOHEADER);
bmi.biPlanes = 1;
bmi.biBitCount = 32;
bmi.biWidth = ScreenX;
bmi.biHeight = -ScreenY;
bmi.biCompression = BI_RGB;
bmi.biSizeImage = 0; // 3 * ScreenX * ScreenY;
int iBegTc = ::GetTickCount();
// Take 100 screen captures for a more accurante measurement of the duration.
for(int i = 0; i < 100; ++i)
{
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, ScreenX, ScreenY);
HDC hdcMem = CreateCompatibleDC (hScreen);
HGDIOBJ hOld = SelectObject(hdcMem, hBitmap);
BitBlt(hdcMem, 0, 0, ScreenX, ScreenY, hScreen, 0, 0, SRCCOPY);
SelectObject(hdcMem, hOld);
GetDIBits(hdcMem, hBitmap, 0, ScreenY, ScreenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
DeleteDC(hdcMem);
DeleteObject(hBitmap);
}
int iEndTc = ::GetTickCount();
printf("%d ms", (iEndTc - iBegTc)/100);
system("PAUSE");
ReleaseDC(GetDesktopWindow(),hScreen);
return 0;
}
我的問題是循環內的代碼執行時間太長。在我的情況下,每次迭代大約需要36 ms。
我想知道是否有語句只能做一次,因此放在循環之外,likI爲字節緩衝區。然而,我不知道哪些是我必須爲每張新圖像做的,哪些是我只能做一次的。
不確定我是否收到您的評論「//以100次屏幕截圖進行更精確的持續時間測量。」我很確定for循環的前三行可能可以在循環之外完成嗎?你試過什麼了? – LBes
那麼目前我還沒有嘗試改變事情而不知道第一。我懷疑,根據我所做的錯誤,例如,由於某些內容未被更新,我可以爲每次迭代使用相同的屏幕截圖,並且由於在不實際顯示它們的情況下比較屏幕截圖並不容易,因此不切實際只是盲目嘗試。 我正在做這個循環多次,因爲根據經驗我知道GetTickCount並不總是非常準確。如果有時15毫秒不準確,那麼這個測量誤差除以迭代的次數。 – Virus721
嗯,當然,但爲什麼你總是分配一些昂貴的資源(循環的前三行),而不是重複使用它們?不分配資源當然不會比分配資源慢,所以這也不是「盲目地嘗試事物」。 – IInspectable