在 Linux 上捕获显示/监视器图像、发送键盘输入
我需要处理发送到笔记本电脑视频显示器的图像,并且需要使用 C++ 或 shell 程序将键盘输入发送到我的 Linux 系统。
我的目标是处理 FPS 游戏中的图像,然后根据这些图像在游戏中采取行动(因此是键盘输入)。我没有试图理解(如果可能的话)如何使用一些 API 与游戏 X 或 Y 交互,而是认为这是与任何游戏交互的最快方式,以某种方式劫持 Linux 输入和输出。
有没有办法在没有任何内核或设备驱动程序黑客攻击的情况下做到这一点?我之前使用 recordmydesktop 将我的桌面录制为视频,我想我可以破解它的代码并尝试从中进行逆向工程。还有其他想法吗?我使用的是 Ubuntu 11。
I need to process images sent to my laptop's video display, and I need to send keyboard input to my Linux system, using a C++ or shell program.
My goal is to process images that are part of an FPS game, then taking action inside that game (hence the keyboard input) based on these images. Instead of trying to understand (if it's even possible) how to interface to game X or Y, using some API, I figured this is the quickest way to interface to any game, hijacking Linux input and output somehow.
Is there any way to do this without any kernel, or device driver hacking? I used recordmydesktop to record my desktop as a video before, I guess I could hack its code and try to reverse-engineer something from that. Any other ideas? I am on Ubuntu 11.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您不需要执行任何与内核或设备驱动程序一样低级别的操作来执行此操作。
例如,您可以使用 XTest X11 扩展 以编程方式伪造输入事件(来自这个发布,有 键盘的另一个例子)。
要捕获图像,最简单的方法是使用 函数插入 (通过
LD_PRELOAD
)来“拦截”对glXSwapBuffers
,每绘制一帧就会调用它。从那里您可以使用glReadPixels< 复制帧缓冲区的内容/code>
并用它做你想做的事。
例如,用于拦截 OpenGL 帧的未经测试的轮廓:
然后您需要将其编译为共享对象,并在运行您正在查看的任何游戏之前
LD_PRELOAD
该共享对象。如果它恰好是 SDL 应用程序,您可以根据需要拦截对
SDL_Flip
或SDL_UpdateRect
的调用。You don't need to do anything as low level as the kernel or device drivers to do this.
You can use the XTest X11 extension to fake input events programatically, for example (from this posting, there's another example for keyboard).
To capture the images the simplest way is to use function interposition (via
LD_PRELOAD
) to "intercept" calls toglXSwapBuffers
, which will be called once each frame is drawn. From there you can copy the contents of the framebuffer, usingglReadPixels
and do with it what you want.E.g. untested outline for intercepting OpenGL frames:
Then you want to compile this as a shared object and
LD_PRELOAD
that shared object before running whatever game you're looking at.If it happens to be an SDL application instead you can intercept the calls to
SDL_Flip
orSDL_UpdateRect
as appropriate.感谢@awoodland的回答,我查找了相关资源,并找到了这个
http://bzr.sesse。 net/glcapture/glcapture.c
我将此代码编译为
并将其加载到脚本中的 FPS 游戏 Urban Terror 中,
运行此脚本时,游戏将被加载。由于某种原因,游戏图形没有显示,但我可以稍后改进。当我退出游戏时,我看到控制台上打印了 gettimeofday 消息,这告诉我钩子起作用了。当我继续处理此代码时,我将提供更多详细信息。
为了发送按键,我点击了链接
http://bharathisubramanian.wordpress.com/2010/03/14/x11-fake-key-event- Generation-using-xtest-ext/
在 Ubuntu 上安装了必要的软件包后然后
fakeKey.c 编译并运行没有问题。
注意:我为此在Github上启动了一个项目,欢迎任何人分叉、提供帮助等。
Thanks to @awoodland's answer, I looked for related resources, and found this
http://bzr.sesse.net/glcapture/glcapture.c
I compile this code as
and load it for FPS game Urban Terror in a script as
The moment this script is ran, the game is loaded. For some reason, the game graphics do not show, but I can improve that later. When I exit the game, I see gettimeofday messages printed on the console, which tells me the hook worked. I'll provide more details as I continue to work this code.
For sending key presses, I followed the link
http://bharathisubramanian.wordpress.com/2010/03/14/x11-fake-key-event-generation-using-xtest-ext/
After I installed the necessary package on Ubuntu with
Then fakeKey.c compiled and worked without problems.
Note: I started a project on Github for this, anyone is welcome to fork, help, etc.
我终于有解决办法了。我相信 UrT 会自行加载 OpenGL,因此诸如 wallhacks 之类的事情是不可能的。那么剩下的最佳选择就是进行 X 次屏幕截图。即使使用像 Python 这样的脚本语言,它的工作速度也相当快。以下代码获取连续的屏幕截图并通过 OpenCV 将它们显示为动画。当然,您需要以最小化模式启动 UrT。 其余详细信息在我的项目中。
另外,为了向游戏发送密钥,上面的方法不起作用,我不得不使用 xdotool 为了向 UrT 发送前向行走密钥,
I finally have a solution. I believe UrT loads OpenGL on its own so that things such as wallhacks, etc are not possible. Then the best remaining option is taking X screenshots. This worked quite fast, even from a scripting language like Python. The following code takes successive screenshots and displays them as an animation through OpenCV. You need to start UrT in minimized mode of course. The rest of the details are in my project.
Also, for sending keys to the game, the method above did not work, I had to use xdotool in order to send forward walk key to UrT,