GUIソフトウェアの回帰テストとしてスクリーンショットを使用しています。各新しいバージョンを展開する前に、一連の自動タスクが古いバージョンと新しいバージョンに対して実行され、両方の場合で各コマンドの後にスクリーンショットが生成され、結果が比較されます。 ImageMagickのインポートコマンドは、そのために非常にうまく機能しています。
最近、右クリックメニューを追加しました。残念ながら、import -window 'id'
はこれらのメニューをキャプチャしません。
Ubuntuのどのコマンドラインツールがウィンドウのスクリーンショットを取り、その上のすべてのウィンドウを撮ることができますか?
つまり、どのツールが、ウィンドウIDに対応するウィンドウのスクリーンショットを撮る代わりに、画面全体のスクリーンショットを撮って、指定されたウィンドウの境界に切り捨てます?
スクリーンショットを撮るための端末コマンドは何ですか? にリストされているツールのいずれでも、この結果を簡単な方法で取得できませんでした。
import
を-screen
オプションとともに使用します。たとえば
import -screen -window 'id' test.png
shutter
およびwmctrl
を使用すると、 このスクリプト の編集バージョンは、説明したとおりになります。the area、aウィンドウが(部分的に)他のウィンドウの下にあるかどうか、およびその方法に関係なく、画面上の特定のウィンドウカバー。
スクリーンショットに含まれるウィンドウの周囲のmargeは任意です。必要に応じてゼロに設定します。
Inkscape
ウィンドウがあり、IDは0x0520000e
で、部分的にいくつかのgedit
ウィンドウで覆われています。引数としてウィンドウの周りのウィンドウIDとマージ(px
内)を使用してスクリプトを実行します。
python3 <script> 0x0520000e 10 10 10 10
(ここで、10 10 10 10
は、左/右/上/下のウィンドウの周囲のpx
のマージです。画像にマージしないように0
に設定します)
結果:
#!/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>
は、 this answer。 のように、ウィンドウの周囲の画像に保持したいマージです。
コマンド例:
python3 /path/to/custom_screenshot.py 0x0520000e 20 20 20 20
Shutter
では、デスクトップの定義された領域のスクリーンショットを撮ることができます。
引数としてウィンドウIDを使用して、スクリプトはwmctrl
(正確にはwmctrl -lG
)の助けを借りてウィンドウの正確な位置を検索し、xprop -id <window_id>
の出力(行_NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 28, 0
例)。
その後、任意のマージで、見つかった領域からスクリーンショットが取得されます。
スクリプトしないは既存のスクリーンショットを上書きします。新しいスクリーンショットの名前は次のとおりです。
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
のトリミングアクションと組み合わせても、ウィンドウの領域のスクリーンショットを作成する非常に高速な方法があります。
まだ十分に速くない?
必要かどうかはわかりませんが、少し書き直すと(下記のスクリプトを参照)、最初にシリーズ全体を撮影することで一連のショットをさらに速くすることが可能になりますthen(その後)doトリミング。ウィンドウがその位置にとどまると仮定すると、これはかなりの時間を節約します:
Scrot
のみで撮影(トリミングなし):
real 0m0.263s
user 0m0.205s
sys 0m0.037s
トリミングを含む撮影:
real 0m0.363s
user 0m0.293s
sys 0m0.040s
最後に、一連のスクリーンショットを作成する例として、EDITで提案されている以下のスクリプトを使用します。
これはfirstすべての画像を連続して撮影します。thenは作成されたすべての画像を一度にトリミングします。
2番目のようなスクリプトを使用しますが、1つの追加の引数:連続したシュートの数、たとえば:
python3 /path/to/custom_screenshot.py 0x0520000e 0 0 0 0 20
ウィンドウ0x0520000e
の20個のスクリーンショットを連続して(数百個も)作成するために、ウィンドウの周囲をマージしません。
#!/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])