如何截取完全被遮挡的窗口的屏幕截图

如何截取完全被遮挡的窗口的屏幕截图

我有一个游戏在后台运行,但我想截取不可见窗口的屏幕截图。似乎 X11 的所有屏幕截图实用程序都需要窗口可见。有没有办法做到这一点?

答案1

这可能是游戏的问题,而不是屏幕截图实用程序的问题。 X11 发送应用程序可见性通知事件告诉他们他们的窗口完全可见、部分被遮挡或完全被遮挡。当窗口完全被遮挡时,大多数应用程序不会费心更新其显示,从而节省资源。换句话说,如果没有人看到它,树就不会倒下。

我认为,如果您向游戏窗口发送 VisibilityNotify 事件以假装它可见,那么您将获得屏幕截图。您需要在窗口被遮挡后发送事件,因为 X11 本身将在那时发送其正常事件。这里是一个未经测试的脚本,用于发送 VisibilityNotify 事件,请使用参数VisibilityPartiallyObscured或来调用它VisibilityUnobscured。关注了一个MapNotify活动,不知道有没有用。您需要 Python 和 Python-xlib。

#! /usr/bin/env python
import re, sys, time
import Xlib.X, Xlib.XK, Xlib.display, Xlib.protocol

def parse_action(string):
    state = {
              '0': 0,
              '1': 1,
              '2': 2,
              'unobscured': 0,
              'partiallyobscured': 1,
              'fullyobscured': 2,
              'visibilityunobscured': 0,
              'visibilitypartiallyobscured': 1,
              'visibilityfullyobscured': 2,
             }[string.lower()]
    return state

def parse_window(display, arg):
    wid = int(arg, 0)
    return display.create_resource_object('window', wid)

def send_event(display, window, state):
    window.send_event(Xlib.protocol.event.VisibilityNotify(window=window,
                                                           state=state))
    window.send_event(Xlib.protocol.event.MapNotify(window=window,
                                                    event=window,
                                                    override=False))
    display.sync()

if __name__ == "__main__":
    display = Xlib.display.Display()
    send_event(display, parse_window(display, sys.argv[1]), parse_action(sys.argv[2]))

答案2

如果您还没有xwd并且xwud已经安装在您的系统上,如果您无法在最多几秒钟内通过包管理器轻松安装它们,我会感到非常惊讶。

% 人xwd

NAME
       xwd - dump an image of an X window

SYNOPSIS
       xwd  [-debug] [-help] [-nobdrs] [-out file] [-xy] [-frame] [-add value]
       [-root | -id id | -name name ] [-icmap] [-screen]  [-silent]  [-display
       display]

DESCRIPTION
       Xwd  is  an X Window System window dumping utility.  Xwd allows X users
       to store window images in a specially formatted dump file.   This  file
       can  then be read by various other X utilities for redisplay, printing,
       editing, formatting, archiving, image processing, etc.  The target win‐
       dow  is  selected  by  clicking the pointer in the desired window.  The
       keyboard bell is rung once at the beginning of the dump and twice  when
       the dump is completed.

了解这是一种桌面会话记录软件 - 内置于 X-server 中 - 它确实使您能够截取屏幕截图等等。但在深入研究之前,您需要先阅读一下文档 - 我认为只是为了熟悉它。

注意 - 目标窗口不需要像上面提到的那样通过鼠标光标选择 - 这只是不带参数调用时的默认行为。整个界面是完全可编写脚本的。

只需再滚动一点,然后...

   -root   This option indicates that the root window should  be  selected
           for  the  window  dump,  without requiring the user to select a
           window with the pointer.

   -id id  This option  indicates  that  the  window  with  the  specified
           resource  id  should  be  selected for the window dump, without
           requiring the user to select a window with the pointer.

如果你接受我的建议,你也会仔细观察xdo工具但不可否认,它在这里的相关性有限。它主要编写鼠标脚本,尽管它确实为 X 后端 api 提供了一些直接的命令行界面 - 正如@Gilles 参考。而且使用起来非常简单。

话虽如此,主要问题是您的显示器当前已被占用。如果你的窗户必须保持不可见,可以用几种方法来处理它——尽管我认为,在你把它们放下之前,你必须先尝试一下。我建议的方法只是将屏幕配置为屏幕大小的两倍。这样,您只需将窗口拖离屏幕即可,它将继续更新显示 - 但不在屏幕上。我可以使用 nvidia 的工具来做到这一点,大多数人都可以做到这一点,xrandr,但是,特别是在 Linux 中,至少根据我的经验,显示问题通常是个人问题,只是因为有很多可能的方法来配置它们。

实现这一点的另一种方法是使用虚拟 X 服务器 - 例如xnest这些xephyr.服务器将整个 X 服务器嵌套在一个窗口中,该窗口可以在后台运行,或者如果您愿意,也可以完全不存在。不幸的是,上次我检查过,这是在不久前,这些正在使用x虚拟驱动程序- 因此对于需要视频加速的视频游戏来说不是一个好的选择。不过,我确信您的手册页可以告诉您更多信息,我只希望我能有所帮助。

相关内容