Я использую скриншоты в качестве регрессионных тестов для программного обеспечения с графическим интерфейсом. Перед развертыванием каждой новой версии выполняется серия автоматических задач со старой и новой версией, в обоих случаях после каждой команды создаются снимки экрана, и результаты сравниваются. Команда импорта в ImageMagick отлично с этим справилась.
Недавно я добавил меню правой кнопки мыши. К сожалению, import -window 'id'
не захватывает эти меню.
Какие инструменты командной строки в Ubuntu могут сделать снимок экрана с окном и всеми окнами поверх него?
То есть, какие инструменты могут, вместо того, чтобы делать скриншот окно, соответствующее идентификатору окна, сделать снимок экрана всего экрана и обрезать его до границ данного окна ?
Я не смог получить этот результат в простой Кстати, с помощью любого из инструментов, перечисленных в . Какова команда терминала для создания снимка экрана? .
Используйте import
с опцией -screen
, например
import -screen -window 'id' test.png
Используя shutter
и wmctrl
, отредактированная версия этого сценария делает в значительной степени точно, что Вы описываете: это делает снимок экрана области, определенное окно покрывает на Вашем экране, неважно, если и как окно (частично) ниже других окон.
marge вокруг окна, чтобы быть включенным в снимок экрана, произволен; обнулите его, если Вам нравится.
Inkscape
окно на моем экране, с идентификатором 0x0520000e
, частично покрытый некоторыми gedit
окна. Я запускаю скрипт с идентификатором окна и marge (в px
) вокруг окна как аргументы:
python3 <script> 0x0520000e 10 10 10 10
(где 10 10 10 10
marge в px
вокруг окна на оставлении/исправлении/превышении/понимании. Набор к 0
не иметь никакого marge в изображении)
Результат:
#!/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])
Читайте man import
. В моем .bashrc
(на самом деле в файле source
г на .bashrc
) я имею:
alias tshhmmss='date +%y%b%d-%H%M%S'
screenshot ()
{
import -window root ~/var/screenshot/$(tshhmmss)_screendump.png
}