gpt4 book ai didi

c++ - 仅从指定窗口捕获像素数据

转载 作者:行者123 更新时间:2023-12-02 10:19:23 24 4
gpt4 key购买 nike

我要 下面的代码只截取指定窗口的屏幕截图,因为这种方式 BitBlt 更快。
下面的代码截取了一个由窗口名称指定的窗口的屏幕截图,将像素数据加载到缓冲区中,然后在屏幕上重新绘制图片,以证明复制有效。

我要 截取浏览器窗口的屏幕截图,例如 Google Chrome,但它似乎不起作用 .它在我的屏幕上绘制了一个具有正确窗口尺寸的黑色矩形。

好像是工作 一直在 Minecraft 的窗口中。

还使用 Tor 浏览器。

我注意到在查询窗口信息后,我的世界的窗口没有 子窗口 ,但是当它不与其他人一起工作时,他们都有多个子窗口。

#include<iostream>
#include<Windows.h>
#include<vector>

using namespace std;

int main() {
HWND wnd = FindWindow(NULL, "Minecraft 1.15.1");//Name of window to be screenshoted
if (!wnd) {
std::cout << "e1\n";
std::cin.get();
return 0;
}
WINDOWINFO wi = { 0 };
wi.cbSize = sizeof(WINDOWINFO);

GetWindowInfo(wnd, &wi);

RECT rect;
GetWindowRect(wnd, &rect);

int width = wi.rcClient.right - wi.rcClient.left;
int height = wi.rcClient.bottom - wi.rcClient.top;

cout << width << height;
/////Fetch window info^^^^^^^^



BYTE* ScreenData = new BYTE[4 * width*height];


// copy screen to bitmap
HDC hScreen = GetWindowDC(wnd);
HDC hDC = CreateCompatibleDC(hScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, width, height);
HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
BitBlt(hDC, 0, 0, width, height, hScreen, 0, 0, SRCCOPY);
SelectObject(hDC, old_obj);

BITMAPINFO bmi = { 0 };
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
std::cout << GetDIBits(hDC, hBitmap, 0, 0, NULL, &bmi, DIB_RGB_COLORS)<<endl;
//std::cout << bmi.bmiHeader.biHeight<< " "<< bmi.bmiHeader.biWidth<<endl;
BYTE*buffer = new BYTE[4* bmi.bmiHeader.biHeight*bmi.bmiHeader.biWidth];
bmi.bmiHeader.biHeight *= -1;
std::cout<<GetDIBits(hDC, hBitmap, 0, bmi.bmiHeader.biHeight, buffer, &bmi, DIB_RGB_COLORS)<<endl;//DIB_PAL_COLORS
/////Load window pixels into a buffer^^^^^^^^


POINT p;
int r = 0;
int g = 0;
int b = 0;
int x = 0;
int y = 0;
HDC sc = GetDC(NULL);
COLORREF color;

while (true) {
if ((y*-1) == bmi.bmiHeader.biHeight+1 && x == bmi.bmiHeader.biWidth-1) { break; }
r = (int)buffer[4 * ((y*bmi.bmiHeader.biWidth) + x)+2];
g = (int)buffer[4 * ((y*bmi.bmiHeader.biWidth) + x)+1];
b = (int)buffer[4 * ((y*bmi.bmiHeader.biWidth) + x) ];
color = RGB(r, g, b);
SetPixel(sc, x, y, color);

x++;
if (x == bmi.bmiHeader.biWidth) {
y++;
x = 0;
}
}
/////Prove that the copying was successful and buffer is full^^^^^^^^
Sleep(5000);
std::cout << "fin\n";
std::cin.get();
return 0;
}

最佳答案

我认为问题在于你做事的顺序。

在将位图放在剪贴板上之前,您应该从内存设备上下文中选择它。

一旦你把位图放在剪贴板上,你就不再拥有它,所以你不应该试图删除它。

最好的方法可能是移动您的 // clean up前段// save bitmap to clipboard部分并消除您的 DelectObject(hBitmap)陈述。所以你的代码的尾端应该是:

BitBlt(hDC, 0, 0, width, height, hScreen, 0, 0, SRCCOPY);

// clean up
SelectObject(hDC, old_obj); // selects hBitmap out of hDC
DeleteDC(hDC);
ReleaseDC(NULL, hScreen);

// save bitmap to clipboard
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap); // clipboard now owns the bitmap
CloseClipboard();

如果这些更改后您仍然有问题,我会检查 SetClipboardData 调用的返回值。如果失败,GetLastError 可能会提供线索。

关于c++ - 仅从指定窗口捕获像素数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60915383/

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