Como tirar um screenshot de uma janela totalmente obscurecida

7

Eu tenho um jogo rodando em segundo plano, mas eu gostaria de tirar screenshots da janela que não é visível. Parece que todos os utilitários de captura de tela do X11 precisam que a janela esteja visível. Existe uma maneira de fazer isso?

    
por marinara 03.04.2014 / 07:37

2 respostas

6

Provavelmente é culpa do jogo, não por culpa do utilitário de captura de tela. O X11 envia aos aplicativos um evento VisibilityNotify para informar que sua janela está totalmente visível, parcialmente obscurecido ou totalmente obscurecido. Quando a janela está totalmente obscurecida, a maioria dos aplicativos não se incomoda em atualizar sua exibição, o que economiza recursos. Em outras palavras, se ninguém está lá para vê-lo, a árvore não cai.

Acho que, se você enviar para a janela do jogo um evento VisibilityNotify para fingir que é visível, você verá sua captura de tela. Você precisará enviar o evento depois que a janela ficar obscura, já que o próprio X11 enviará seu evento normal naquele momento. Aqui é um script não testado que envia um evento VisibilityNotify, chame-o com o argumento VisibilityPartiallyObscured ou VisibilityUnobscured . Eu sigo com um evento MapNotify , não sei se é útil. Você precisa do Python e do 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]))
    
por 04.04.2014 / 01:40
3

Se você não tem xwd e xwud já instalado no seu sistema, eu ficaria muito surpreso se você não pudesse instalá-los facilmente através do gerenciador de pacotes em alguns segundos no máximo.

% man 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.

Entenda que este é um tipo de software de gravação de sessão de desktop - embutido no X-server - ele permite tirar screenshots e muito mais. Mas você vai querer ler a documentação um pouco antes de mergulhar - só para se familiarizar com ela, eu acho.

Nota - a janela de destino não precisa ser selecionada via cursor do mouse como mencionado acima - é apenas o comportamento padrão quando é invocado sem argumentos. A interface inteira é totalmente programável por scripts.

Basta rolar um pouco mais e ...

   -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.

Se você seguir meu conselho, você também vai olhar bem de perto xdotool , admitidamente, tem relevância limitada aqui. Ele rotula o mouse principalmente, embora ofereça alguma interface de linha de comando direta para o X backend api - como referências @Gilles. E é bem simples de usar.

Tudo isso, a principal questão é que seu monitor está ocupado no momento. Se a sua janela deve permanecer invisível, é possível lidar com ela de algumas maneiras - embora você tenha que tentar um pouco, acho, antes de tirá-las. A maneira que eu recomendaria é apenas configurar sua tela para ter o dobro do tamanho da sua tela. Dessa forma, você pode simplesmente arrastar a janela para fora da tela e ela continuará atualizando a tela - mas fora da tela. Eu posso fazer isso com as ferramentas da nvidia, e a maioria pode fazer isso com xrandr, mas, especialmente no Linux, pelo menos na minha experiência, os problemas de exibição são frequentemente problemas pessoais apenas porque há tantas maneiras possíveis de configurá-los. / p>

Outra maneira de fazer isso é com um X-server virtual - como xnest ou xephyr. . Esses servidores aninham um X-server inteiro em uma janela que pode ser em segundo plano ou completamente inexistente se você preferir. A última vez que verifiquei, que há algum tempo infelizmente, eles estavam usando o xdummy-driver - e, portanto, não seriam boas escolhas para um videogame que exigia aceleração de vídeo. Ainda assim, tenho certeza de que seus manuais poderiam dizer mais a você, e só espero que tenha ajudado.

    
por 04.04.2014 / 11:49