我正在尝试制作一个程序,用于制作整个桌面或特定窗口的屏幕截图,并在SFML窗口中绘制。最初它很好,但10秒后它停止捕获。我还注意到,即使我们只谈到每秒20kb的速度,它也会消耗RAM。我试图加入在网络上找到的代码。当它停止工作时,它打印“2”然后无限“1”,从代码中你很快意识到这些错误的位置。
#include <SFML/Graphics.hpp>
#include <Windows.h>
HBITMAP ScreenShot(HWND hParent, int x, int y, int nWidth, int nHeight)
{
//Get a DC from the parent window
HDC hDC = GetDC(hParent);
//Create a memory DC to store the picture to
HDC hMemDC = CreateCompatibleDC(hDC);
//Create the actual picture
HBITMAP hBackground = CreateCompatibleBitmap(hDC, nWidth, nHeight);
//Select the object and store what we got back
HBITMAP hOld = (HBITMAP)SelectObject(hMemDC, hBackground);
//Now do the actually painting into the MemDC (result will be in the selected object)
//Note: We ask to return on 0,0,Width,Height and take a blit from x,y
BitBlt(hMemDC, 0, 0, nWidth, nHeight, hDC, x, y, SRCCOPY);
//Restore the old bitmap (if any)
SelectObject(hMemDC, hOld);
//Release the DCs we created
ReleaseDC(hParent, hMemDC);
ReleaseDC(hParent, hDC);
//Return the picture (not a clean method, but you get the drill)
return hBackground;
}
bool SFMLLoadHBitmapAsImage(HBITMAP hBitmap, sf::Image *pPicture)
{
HWND hParent = FindWindow(NULL, TEXT("Calculator"));
//if (hParent == NULL)printf("%s", "w");
//Create a DC to get hBitmap information
HDC hDC = GetDC(hParent);
//Create BITMAPINFO variable, set size
BITMAPINFO MyBMInfo = { 0 };
MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);
//Get the BITMAPINFO structure from the bitmap
if (0 == GetDIBits(hDC, hBitmap, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS))
{
printf("%s", "1");
return false;
}
//Create the bitmap pixel array each element is [b,g,r]
BYTE* lpPixels = new BYTE[MyBMInfo.bmiHeader.biSizeImage];
//Setting up the structure of the buffer to be received
MyBMInfo.bmiHeader.biCompression = BI_RGB; // No-compression
//Now get the actual data from the picture
if (0 == GetDIBits(hDC, hBitmap, 0, MyBMInfo.bmiHeader.biHeight, (LPVOID)lpPixels, &MyBMInfo, DIB_RGB_COLORS))
{
printf("%s", "2");
return false;
}
//Now create an array of SFML pixels we want to fill
sf::Uint8 *lpPixelWithAlpha = new sf::Uint8[MyBMInfo.bmiHeader.biSizeImage +
(MyBMInfo.bmiHeader.biSizeImage / 3) / 3]; //Add room for alpha
//Loop through each pixel, with steps of four RGBA!
for (int x = 0; x < MyBMInfo.bmiHeader.biSizeImage; x += 4)
{
lpPixelWithAlpha[x] = lpPixels[x + 2]; //lpPixels = r
lpPixelWithAlpha[x + 1] = lpPixels[x + 1]; //lpPixels = g
lpPixelWithAlpha[x + 2] = lpPixels[x]; //lpPixels = b
lpPixelWithAlpha[x + 3] = 255; //Nada alpha (just to adjust if you like)
}
//Remove old DIBsection
delete[] lpPixels;
//Load picture, now with correct pixels and alpha channel
pPicture->create(MyBMInfo.bmiHeader.biWidth,
MyBMInfo.bmiHeader.biHeight, lpPixelWithAlpha);
//Remove the pixels with alphachannel
delete[] lpPixelWithAlpha;
//Release the DC
ReleaseDC(hParent, hDC);//::GDW()
//Notify ok!
return true;
}
int main()
{
.....
hBitmap = ScreenShot(FindWindow(NULL, TEXT("Calculator")), 0, 0, 640, 400);
SFMLLoadHBitmapAsImage(hBitmap, &picture);
.....
}