行。 我想这样做:
while(1)
{
CaptureScreenshot (as BMP)
Convert screenshot to 24 bit instead of 32 bit
Resize screenshot size
Get the BMP bits array of the resized screenshot
}
我有它的工作,但我能得到的最好的是每秒18次迭代(截图)。 我需要更多,我想请你帮我改进。
这就是我的所作所为:
Start()
{
ULONG_PTR gdiplusToken=0;
HDC mhCompatibleDC;
HBITMAP mhCompatibleBitmap;
HWND mhDesktopWnd;
HDC mhDesktopDC;
byte*piRGB=new byte[1200*900*3]
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
mhDesktopDC = GetDC(GetDesktopWindow());
mhCompatibleDC = CreateCompatibleDC(mhDesktopDC);
mhCompatibleBitmap = CreateCompatibleBitmap(mhDesktopDC, 1440, 900);
SelectObject(mhCompatibleDC, mhCompatibleBitmap);
moResizeImage = new Bitmap(1200, 900, PixelFormat24bppRGB);
moGraphics = Gdiplus::Graphics::FromImage(moResizeImage);
//as you can see to optimize the code, i pre allocate the CompatibleDC (which speed things)
//I also use the same moGraphics and not creating moResizeImage again and again - BUT from my tests
//that does not speed things so i guess that DrawImage reallocate moResizeImage memory on each call
While(1)
{
BitBlt(mhCompatibleDC, 0, 0, 1440, 900, mhDesktopDC, 0, 0, SRCCOPY)
Bitmap oOrgDesktopImage(mhCompatibleBitmap, NULL);//here i have the original desktop image 32 bit (as my display)
moGraphics->DrawImage(&oOrgDesktopImage, 0, 0, 1200, 900);(here it converts it to 24 bit as i need and do the resize)
//now I take the bits part of the BMP and copy it to piRGB
Gdiplus::BitmapData bitmapData;
Gdiplus::Rect rect(0, 0, 1200, 900);
if (Gdiplus::Ok == moResizeImage->LockBits(&rect, Gdiplus::ImageLockModeRead , moResizeImage->GetPixelFormat(),&bitmapData))
{
int len = bitmapData.Height * std::abs(bitmapData.Stride);
for (int i = 0; i < len; i = i + 1)//18
{
*piRGB = ((BYTE*)bitmapData.Scan0)[i++];
piRGB++;
}
moResizeImage->UnlockBits(&bitmapData);
}
//here i do things with piRGB but these things are not counted it the timer so you can assume here the code ends
//as said as the code looks now, i can fill piRGB ~18 times (18loops) in 1 second. I must improve that/
//my knowledge in GDI is very poor and i hope you can provide code to your suggestions - THANKS
}
如果我们看看while部分,那么它每秒运行18次。 如果我删除了while中的所有代码而只留下了 BitBlt调用 然后我每秒得到300个循环。 如果我加了 位图oOrgDesktopImage(mhCompatibleBitmap,NULL); 我每秒得到160个循环。 如果我添加moGraphics-&gt; DrawImage(&amp; oOrgDesktopImage,0,0,1200,900)调用 我每秒得到19个循环。 添加其余代码(for循环)将其减少到18个循环
答案 0 :(得分:0)
Start(){
HDC mhCompatibleDC, mhDesktopDC, hdc;
HBITMAP hBitmap, hBitmapOld;
unsigned char *piRGB= NULL;
int i;
mhDesktopDC = GetDC(GetDesktopWindow());
hdc = CreateIC(TEXT("DISPLAY"), NULL, NULL, NULL);
mhCompatibleDC = CreateCompatibleDC(hdc);
hBitmap = NewDIBSection(1200, 900, (void **)&piRGB);
if(hBitmap == NULL){/* Error */}
hBitmapOld = SelectObject(mhCompatibleDC, hBitmap);
//Now piRGB points to RGB data of mhCompatibleDC
DeleteDC(hdc);
//SetStretchBltMode(mhCompatibleDC, HALFTONE); //for better quality
for(i = 0; i < 200; i++){
BitBlt(mhCompatibleDC, 0, 0, 1200, 900, mhDesktopDC, 0, 0, SRCCOPY);
//StretchBlt(mhCompatibleDC, 0, 0, 1200, 900, mhDesktopDC, 0, 0, 1440, 900, SRCCOPY);
}
SelectObject(mhCompatibleDC, hBitmapOld);
DeleteDC(mhCompatibleDC);
DeleteObject(hBitmap);
ReleaseDC(GetDesktopWindow(), mhDesktopDC);
}
HBITMAP NewDIBSection(int cx, int cy, void **ppBits){
HBITMAP hbitmap = NULL;
LPBITMAPINFO lpbmi;
HDC hdc;
lpbmi = (LPBITMAPINFO)calloc(1, sizeof (BITMAPINFO) + 4 * sizeof(DWORD));
if(!lpbmi){return NULL;}
ZeroMemory(&lpbmi->bmiHeader, sizeof(BITMAPINFOHEADER));
lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbmi->bmiHeader.biWidth = cx;
lpbmi->bmiHeader.biHeight = -cy;
lpbmi->bmiHeader.biPlanes = 1;
lpbmi->bmiHeader.biBitCount = 24;
lpbmi->bmiHeader.biCompression = BI_RGB;
hdc = CreateIC(TEXT("DISPLAY"), NULL, NULL, NULL);
hbitmap = CreateDIBSection(hdc, lpbmi, DIB_RGB_COLORS, ppBits, NULL, 0);
DeleteDC(hdc);
free(lpbmi);
return hbitmap;
}
测试结果:
BitBlt -> 368 msec
StretchBlt -> 2,5 - 3,6 sec!
瓦尔特