gpt4 book ai didi

c++ - 使用 BitBlt 捕获程序窗口总是返回相同的图像

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:19:11 26 4
gpt4 key购买 nike

我编写了以下代码 (C++ Win32) 来捕获游戏窗口屏幕并从图像中获取像素颜色数组。函数 autoB() 完成这项工作。

然后我将结果数组绘制到我的窗口中以直观地检查我得到了什么。

问题是这个程序只在我启动计算机后运行一次,在第一次“缓存”从游戏中截取的第一个屏幕截图后,我总是得到相同的像素阵列。即使我关闭并重新启动程序,我也会得到相同的屏幕截图。

游戏未使用 DirectX 在屏幕上绘图,我始终可以使用 Alt+PrtSc 截取屏幕截图。

如果您能帮助理解为什么会这样发生,我们将不胜感激。

int getPixels(HDC *eClientHdcMem, HBITMAP *eClientBmp, unsigned char **lp) {

BITMAP bmpScreen;
BITMAPINFOHEADER bi;

GetObject(*eClientBmp, sizeof(BITMAP), &bmpScreen);

LONG bW = bmpScreen.bmWidth, bH = bmpScreen.bmHeight;

bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bW;
bi.biHeight = -bH;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;

DWORD dw = ((bW * bi.biBitCount + 31) / 32) * 4 * bH;
*lp = new unsigned char[dw];

return GetDIBits(*eClientHdcMem, *eClientBmp, 0, (UINT)bH, *lp, (BITMAPINFO *)&bi, DIB_RGB_COLORS);

}

void autoB() {
HWND hwnd;
HDC hDC0 = NULL, eClientHdcMem = NULL;
HBITMAP eClientBmp = NULL;
BITMAP bmp = {0};
unsigned char *lp = NULL, *sp = NULL;
WINDOWINFO wi;
wi.cbSize = sizeof(WINDOWINFO);
RECT vp;
int vpW, vpH;
long iW, iH;

if (!(hwnd = FindWindow(NULL,TEXT("Client")))) return;
if (!(hDC0 = GetDC(hwnd))) return;

GetWindowInfo(hwnd,&wi);
vp = wi.rcClient;
vpW = vp.right - vp.left;
vpH = vp.bottom - vp.top;

if (!(eClientBmp = CreateCompatibleBitmap(hDC0, vpW, vpH))) return;
if (!(eClientHdcMem = CreateCompatibleDC(hDC0))) return;
SelectObject(eClientHdcMem, eClientBmp);

BitBlt(eClientHdcMem, 0, 0, vpW, vpH, hDC0, 0, 0, SRCCOPY);

int res = getPixels(&eClientHdcMem, &eClientBmp, &lp);

DeleteObject(eClientBmp);
DeleteObject(eClientHdcMem);

// begin testing
HDC sts = GetDC(hStats);
HBITMAP stsBmp = CreateCompatibleBitmap(sts, vpW, vpH);
HBITMAP stsBmpOld = (HBITMAP)SelectObject(sts, stsBmp);
unsigned char r,g,b;
for(unsigned int i=0;i<vpW;i++) {
for(unsigned int j=0;j<vpH;j++) {
r = lp[(vpW*j+i) * 4 + 2];
g = lp[(vpW*j+i) * 4 + 1];
b = lp[(vpW*j+i) * 4 + 0];
SetPixel(sts,i,j,RGB(r,g,b));
}
}
SelectObject(sts, stsBmpOld);
DeleteObject(stsBmp);
DeleteObject(stsBmpOld);
ReleaseDC(hStats,sts);
// end testing

DeleteDC(eClientHdcMem);
ReleaseDC(hwnd,hDC0);

delete [] lp;
lp = NULL;
delete [] sp;
sp = NULL;

}

更改屏幕截图的唯一方法是重新启动游戏。然后,无论游戏窗口中发生了什么,第一个屏幕截图都会被捕获并一遍又一遍地显示。

最佳答案

您确定返回相同的像素,还是只是在调试窗口的屏幕上看到相同的图像?原始图像复制代码看起来不错,但在您的“调试”代码中,即使您直接调用 SetPixel(),您仍然需要调用 InvalidateRect() 以使 Windows 发送新的 WM_PAINT 消息.如果您不这样做,您可能只是在查看旧图像,即使新位确实已被捕获(但未绘制)。

关于c++ - 使用 BitBlt 捕获程序窗口总是返回相同的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11197705/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com