如何快速获取并处理实时屏幕输出

发布于 2024-09-04 06:46:06 字数 1616 浏览 5 评论 0原文

我正在尝试编写一个程序来玩全屏电脑游戏(作为计算机视觉和人工智能的实验)。

对于这个实验,我假设游戏没有供 AI 玩家使用的底层 API(也没有可用的源),因此我打算处理游戏在屏幕上呈现的视觉信息。

游戏在 win32 系统上以全屏模式运行(我假设是 direct-X)。

目前我正在使用 win32 函数

#include <windows.h>
#include <cvaux.h>
class Screen {
    public:
    HWND    windowHandle;
    HDC     windowContext;
    HBITMAP buffer;
    HDC     bufferContext;
    CvSize  size;
    uchar*  bytes;
    int channels;
Screen () {
    windowHandle = GetDesktopWindow();
    windowContext   = GetWindowDC (windowHandle);
    size = cvSize (GetDeviceCaps (windowContext, HORZRES), GetDeviceCaps (windowContext, VERTRES));
    buffer = CreateCompatibleBitmap (windowContext, size.width, size.height);
    bufferContext = CreateCompatibleDC (windowContext);
    SelectObject (bufferContext, buffer);
    channels = 4;
    bytes = new uchar[size.width * size.height * channels];
}

~Screen () {
    ReleaseDC(windowHandle, windowContext);
    DeleteDC(bufferContext);
    DeleteObject(buffer);
    delete[] bytes;
}

void CaptureScreen (IplImage* img) {
    BitBlt(bufferContext, 0, 0, size.width, size.height, windowContext, 0, 0, SRCCOPY);
    int n = size.width * size.height;
    int imgChannels = img->nChannels;

    GetBitmapBits (buffer, n * channels, bytes); 

    uchar* src = bytes;
    uchar* dest = (uchar*) img->imageData;
    uchar* end  = dest + n * imgChannels;

    while (dest < end) {
        dest[0] = src[0];
        dest[1] = src[1];
        dest[2] = src[2];

        dest  += imgChannels;
        src += channels;
    }
}

使用这种方法处理帧的速度太慢了。有没有更好的方法来获取屏幕帧?

I am trying to write a program to play a full screen PC game for fun (as an experiment in Computer Vision and Artificial Intelligence).

For this experiment I am assuming the game has no underlying API for AI players (nor is the source available) so I intend to process the visual information rendered by the game on the screen.

The game runs in full screen mode on a win32 system (direct-X I assume).

Currently I am using the win32 functions

#include <windows.h>
#include <cvaux.h>
class Screen {
    public:
    HWND    windowHandle;
    HDC     windowContext;
    HBITMAP buffer;
    HDC     bufferContext;
    CvSize  size;
    uchar*  bytes;
    int channels;
Screen () {
    windowHandle = GetDesktopWindow();
    windowContext   = GetWindowDC (windowHandle);
    size = cvSize (GetDeviceCaps (windowContext, HORZRES), GetDeviceCaps (windowContext, VERTRES));
    buffer = CreateCompatibleBitmap (windowContext, size.width, size.height);
    bufferContext = CreateCompatibleDC (windowContext);
    SelectObject (bufferContext, buffer);
    channels = 4;
    bytes = new uchar[size.width * size.height * channels];
}

~Screen () {
    ReleaseDC(windowHandle, windowContext);
    DeleteDC(bufferContext);
    DeleteObject(buffer);
    delete[] bytes;
}

void CaptureScreen (IplImage* img) {
    BitBlt(bufferContext, 0, 0, size.width, size.height, windowContext, 0, 0, SRCCOPY);
    int n = size.width * size.height;
    int imgChannels = img->nChannels;

    GetBitmapBits (buffer, n * channels, bytes); 

    uchar* src = bytes;
    uchar* dest = (uchar*) img->imageData;
    uchar* end  = dest + n * imgChannels;

    while (dest < end) {
        dest[0] = src[0];
        dest[1] = src[1];
        dest[2] = src[2];

        dest  += imgChannels;
        src += channels;
    }
}

The rate at which I can process frames using this approach is much too slow. Is there a better way to acquire screen frames?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一片旧的回忆 2024-09-11 06:46:06

作为一般方法,我会挂接缓冲区翻转函数调用,以便可以捕获每个帧上的帧缓冲区。

http://easyhook.codeplex.com/

As a general method, I would hook the buffer-flipping function calls so I can capture the framebuffer on every frame.

http://easyhook.codeplex.com/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文