Как мне сделать скриншот окна и всех окон поверх него?

Я использую скриншоты в качестве регрессионных тестов для программного обеспечения с графическим интерфейсом. Перед развертыванием каждой новой версии выполняется серия автоматических задач со старой и новой версией, в обоих случаях после каждой команды создаются снимки экрана, и результаты сравниваются. Команда импорта в ImageMagick отлично с этим справилась.

Недавно я добавил меню правой кнопки мыши. К сожалению, import -window 'id' не захватывает эти меню.

Какие инструменты командной строки в Ubuntu могут сделать снимок экрана с окном и всеми окнами поверх него?

То есть, какие инструменты могут, вместо того, чтобы делать скриншот окно, соответствующее идентификатору окна, сделать снимок экрана всего экрана и обрезать его до границ данного окна ?

Я не смог получить этот результат в простой Кстати, с помощью любого из инструментов, перечисленных в . Какова команда терминала для создания снимка экрана? .

5
задан 8 February 2016 в 00:11

3 ответа

Используйте import с опцией -screen, например

import -screen -window 'id' test.png
0
ответ дан 8 February 2016 в 00:11

Используя shutter и wmctrl, отредактированная версия этого сценария делает в значительной степени точно, что Вы описываете: это делает снимок экрана области, определенное окно покрывает на Вашем экране, неважно, если и как окно (частично) ниже других окон.

marge вокруг окна, чтобы быть включенным в снимок экрана, произволен; обнулите его, если Вам нравится.

На практике

  • Я имею Inkscape окно на моем экране, с идентификатором 0x0520000e, частично покрытый некоторыми gedit окна.
  • Я запускаю скрипт с идентификатором окна и marge (в px) вокруг окна как аргументы:

    python3 <script> 0x0520000e 10 10 10 10 
    

    (где 10 10 10 10 marge в px вокруг окна на оставлении/исправлении/превышении/понимании. Набор к 0 не иметь никакого marge в изображении)

    Результат:

    enter image description here

Сценарий

#!/usr/bin/env python3
import subprocess
import time
import sys

"""
On different window managers, the window geometry as output of wmctrl differs slightly.
The "deviation" should compensate these differences. Most likely appropriate (tested) settings:
Unity: 0, Gnome: -36, Xfce (Xubuntu): -26, KDE (Kubuntu): 0
"""
#---
deviation = 0
#---

get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
time.sleep(0.5)
# targeted window
target = sys.argv[1]; arg = sys.argv[2:]
f_data = [l.split() for l in get("wmctrl -lG").splitlines() if target in l][0][2:6]
xt_data = get("xprop -id "+target).split()
xt_i = xt_data.index("_NET_FRAME_EXTENTS(CARDINAL)")
xt = [int(n.replace(",", "")) for n in xt_data[xt_i+2:xt_i+6]]
# set data for screenshot command
x = str(int(f_data[0])-int(arg[0])-xt[0])
y = str(int(f_data[1])-int(arg[2])-xt[2]+deviation)
w = str(int(f_data[2])+int(arg[0])+int(arg[1])+xt[0]+xt[1])
h = str(int(f_data[3])+int(arg[3])+int(arg[2])+xt[2]+xt[3])

command = "shutter -s="+(",").join([x,y,w,h])+" -e"
subprocess.call(["/bin/bash", "-c", command])

Как использовать

  • Использование сценария Shutter и wmctrl:

    sudo apt-get install wmctrl shutter
    
  • Скопируйте сценарий ниже в пустой файл, сохраните его как custom_screenshot.py.

  • Выполните его командой:

    python3 /path/to/custom_screenshot.py <window_id> <left> <right> <top> <bottom>
    

    где, <left> <right> <top> <bottom> слияния, как которые требуется сохранить в изображении вокруг окна, в этом ответе.

    Команда Example:

    python3 /path/to/custom_screenshot.py 0x0520000e 20 20 20 20
    

Объяснение

  • В Shutter, возможно сделать снимок экрана определенной области рабочего стола.

  • С идентификатором окна как аргумент сценарий ищет точное положение окна с помощью wmctrl (wmctrl -lG быть точным), и вывод xprop -id <window_id> (в строке _NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 28, 0 например).

  • Впоследствии, снимок экрана сделан от найденной области с произвольным marge.

Примечание:

Сценарий не перезаписывает существующие снимки экрана. Новые снимки экрана называют:

outputfile_1.png
outputfile_2.png
outputfile_3.png

и так далее...


Править

Так как Вы упомянули в комментарии, что скорость является проблемой:

На основе этого сценария, если мы делаем точно тот же прием, но использование Scrot вместо Shutter, мы можем пропустить sleep 0.5 и сделайте его намного быстрее:

Сценарий

#!/usr/bin/env python3
import subprocess
import sys
import os

"""
On different window managers, the window geometry as output of wmctrl differs slightly.
The "deviation" should compensate these differences. Most likely appropriate (tested) settings:
Unity: 0, Gnome: -36, Xfce (Xubuntu): -26, KDE (Kubuntu): 0
"""
#---
deviation = 0
#---

get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
# targeted window
target = sys.argv[1]; arg = sys.argv[2:]
f_data = [l.split() for l in get("wmctrl -lG").splitlines() if target in l][0][2:6]
xt_data = get("xprop -id "+target).split()
xt_i = xt_data.index("_NET_FRAME_EXTENTS(CARDINAL)")
xt = [int(n.replace(",", "")) for n in xt_data[xt_i+2:xt_i+6]]
# set data for screenshot command
x = str(int(f_data[0])-int(arg[0])-xt[0])
y = str(int(f_data[1])-int(arg[2])-xt[2]+deviation)
w = str(int(f_data[2])+int(arg[0])+int(arg[1])+xt[0]+xt[1])
h = str(int(f_data[3])+int(arg[3])+int(arg[2])+xt[2]+xt[3])

# setting default directories / filenames
home = os.environ["HOME"]
temp = home+"/"+".scrot_images"
img_in = temp+"/in.png"
# if you prefer, you can change the two line below:
output_directory = home+"/"+"scrot_images" # output directory
filename = "outputfile"                    # filename
# creating needed directories
for dr in [temp, output_directory]:
    if not os.path.exists(dr):
        os.mkdir(dr)
# creating filename (-number) to prevent overwriting previous shots
n = 1
while True:
    img_out = output_directory+"/"+filename+"_"+str(n)+".png"
    if os.path.exists(img_out):
        n = n+1
    else:
        break
# Take screnshot, crop image
subprocess.call(["scrot", img_in])
subprocess.Popen(["convert", img_in, "-crop", w+"x"+h+"+"+x+"+"+y, "+repage", img_out])

Использовать

Используйте его точно как первый сценарий, только:

  • Этот сценарий потребности scrot, imagemagick и wmctrl

    sudo apt-get install imagemagick wmctrl scrot
    
  • изображения будут сохранены в ~/scrot_images

Объяснение

В то время как первый сценарий использует параметр командной строки Shutter стрелять в определенный раздел рабочего стола, Scrot не поддерживает это. Это только делает снимок экрана целого экрана.

Мы можем объединиться однако imagemagickопция сделать купюру изображения, с методом для нахождения координат точного окна мы использовали в первом сценарии, и обрежьте изображение соответственно.
С тех пор Scrot чрезвычайно легкий вес и быстрый, даже объединенный с imagemagickдействие обрезки, у нас есть довольно быстрый способ сделать снимки экрана области окна.

Все еще достаточно быстро?

Не уверенный, если бы это необходимо, но с небольшим количеством перезаписи (см. сценарий ниже), это было бы возможно сделать серию выстрелов еще быстрее первой охотой целым рядом, затем (впоследствии) сделало бы обрезку. Принятие окна осталось бы в его положении, это сохранит значительное количество времени:

  • Стрельба только с Scrot (никакая обрезка):

    real    0m0.263s
    user    0m0.205s
    sys     0m0.037s
    
  • Стрельба, включая обрезку:

    real    0m0.363s
    user    0m0.293s
    sys     0m0.040s
    

Последовательная стрельба

Наконец, как пример для создания ряда снимков экрана, сценария ниже, как предложено в РЕДАКТИРОВАНИИ.
Эти первые выстрелы все изображения подряд, затем делает обрезку на всех созданных изображениях сразу.

Используйте сценарий как второй, но с одним дополнительным аргументом: количество выстрелов подряд, например:

python3 /path/to/custom_screenshot.py 0x0520000e 0 0 0 0 20

сделать 20 снимков экрана окна 0x0520000e в строке (могли быть сотни), никакой marge вокруг окна.

Сценарий

#!/usr/bin/env python3
import subprocess
import sys
import os

"""
On different window managers, the window geometry as output of wmctrl differs slightly.
The "deviation" should compensate these differences. Most likely appropriate (tested) settings:
Unity: 0, Gnome: -36, Xfce (Xubuntu): -26, KDE (Kubuntu): 0
"""
#---
deviation = 0
#---

get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
# targeted window
target = sys.argv[1]; arg = sys.argv[2:]
f_data = [l.split() for l in get("wmctrl -lG").splitlines() if target in l][0][2:6]
xt_data = get("xprop -id "+target).split()
xt_i = xt_data.index("_NET_FRAME_EXTENTS(CARDINAL)")
xt = [int(n.replace(",", "")) for n in xt_data[xt_i+2:xt_i+6]]
# set data for screenshot command
x = str(int(f_data[0])-int(arg[0])-xt[0])
y = str(int(f_data[1])-int(arg[2])-xt[2]+deviation)
w = str(int(f_data[2])+int(arg[0])+int(arg[1])+xt[0]+xt[1])
h = str(int(f_data[3])+int(arg[3])+int(arg[2])+xt[2]+xt[3])
# setting default directories / filenames
home = os.environ["HOME"]
temp = home+"/"+".scrot_images"
# if you prefer, you can change the two line below:
output_directory = home+"/"+"scrot_images" # output directory
filename = "outputfile"                    # filename
# creating needed directories
for dr in [temp, output_directory]:
    if not os.path.exists(dr):
        os.mkdir(dr)
# do the shooting
t = 0; l = []; shots = int(sys.argv[6])
while t < shots:
    img_temp = temp+"/"+str(t)+"in.png"
    l.append(img_temp)
    # reading arguments,arranging commands to perform
    subprocess.call(["scrot", img_temp])
    t += 1
# do the cropping on all images in a row
for img in l:
    n = 1
    while True:
        img_out = output_directory+"/"+filename+"_"+str(n)+".png"
        if os.path.exists(img_out):
            n = n+1
        else:
            break
    subprocess.call(["convert", img , "-crop", w+"x"+h+"+"+x+"+"+y, "+repage", img_out])
6
ответ дан 8 February 2016 в 00:11

Читайте man import. В моем .bashrc (на самом деле в файле source г на .bashrc) я имею:

alias tshhmmss='date +%y%b%d-%H%M%S'
screenshot ()
{
   import -window root ~/var/screenshot/$(tshhmmss)_screendump.png
}
-2
ответ дан 8 February 2016 в 10:11
  • 1
    Большое спасибо! I' m испытывающий некоторые решения - я обновил встроенное микропрограммное обеспечение и изменил регулирующий домен. Я can' t, кажется, находят опцию WPA2-AES на моей вкладке соединений редактирования, таким образом, that' s все еще набор к WPA и WPA2 Персональный. I' ll возвращаются к Вам приблизительно через один день после наблюдения поведения. Спасибо! – Siddharth Krishnamoorthy 5 May 2017 в 20:24

Другие вопросы по тегам:

Похожие вопросы: