分别截取多个显示器的命令行工具
Command line tool to Screenshot multiple monitors separately
问题陈述
我使用 scrot
截取屏幕截图,除非我有多个监视器或显示器,否则效果很好。在这种情况下 scrot
将不同显示器的屏幕截图合并为一个输出。
根据联机帮助页,scrot
支持选项 -m
:
-m, --multidisp
For multiple heads, grab shot from each and join them together.
所以我想默认行为是 NOT 将它们连接在一起。然而,这种情况并非如此。即使没有 -m
选项,我也会加入屏幕截图。
我很乐观 scrot
应该能够做到这一点,因为它支持 -u
选项:
-u, --focused
Use the currently focused window.
效果很好。
我还查看了另一个名为 maim
的 CLI 工具 - 但我还是不知道如何分别截取不同显示器的屏幕截图。
所以我排除的解决方案应该像这样工作:
screenshot_command <display_name> # and other options
只截屏显示 <display_name>
。
我目前尝试的解决方案
maim
支持 curios looking 选项 -x
:
-x, --xdisplay=hostname:number.screen_number
Sets the xdisplay to use.
所以我尝试了 maim -x 0.0 | xclip -selection clipboard -t image/png
,但这不起作用。我不知道这个选项是如何使用的,因为没有足够的文档。
scrot
和maim
都支持选项-s
:
-s, --select
Interactively select a window or rectangle with the mouse.
所以我正在想象一个非常丑陋/骇人听闻的解决方案,使用xdotool
(或类似)到select所需的显示并使用选项-s
到 maim
或 scrot
可以完成这项工作。但我宁愿不走这条路,除非没有其他直接的解决方案。
胡思乱想
我想知道这个问题是否是因为我添加新显示器的方式?我通常使用如下命令添加我的第二个显示器:
xrandr --output eDP-1 --auto --output HDMI-1-4 --auto --right-of eDP-1
所以我想知道,可能是scrot
或maim
有只有一个显示。我想是因为 xdpyinfo | grep -A4 '^screen'
和 ONE 监视器的输出看起来像:
$ xdpyinfo | grep -A4 '^screen'
screen #0:
dimensions: 1920x1080 pixels (506x285 millimeters)
resolution: 96x96 dots per inch
depths (7): 24, 1, 4, 8, 15, 16, 32
root window id: 0x1ba
和 两个 显示器看起来像这样:
$ xdpyinfo | grep -A4 '^screen'
screen #0:
dimensions: 3280x1080 pixels (865x285 millimeters)
resolution: 96x96 dots per inch
depths (7): 24, 1, 4, 8, 15, 16, 32
root window id: 0x1ba
如果这确实是我出现问题的原因,那么我应该如何添加我的第二台显示器?
另一个解决方案是MSS。
安装非常简单(不需要昂贵的 Python 模块):
$ python3 -m pip install --user -U mss
它将添加一个新的 mss
可执行文件,您可以随时调用。
例如,要获取每台显示器的屏幕截图,只需键入:
$ mss
/home/USER/monitor-1.png
/home/USER/monitor-2.png
/home/USER/monitor-3.png
如果只想捕获第一个监视器:
$ mss --monitor 1
/home/USER/monitor-1.png
要在一张图片中捕获所有监视器的屏幕截图(如 scrot 所做的那样):
$ mss --monitor -1
/home/USER/monitor-0.png
截至目前,帮手显示:
$ mss --help
usage: mss [-h] [-c COORDINATES] [-l {0,1,2,3,4,5,6,7,8,9}] [-m MONITOR]
[-o OUTPUT] [-q] [-v]
optional arguments:
-h, --help show this help message and exit
-c COORDINATES, --coordinates COORDINATES
the part of the screen to capture: top, left, width,
height
-l {0,1,2,3,4,5,6,7,8,9}, --level {0,1,2,3,4,5,6,7,8,9}
the PNG compression level
-m MONITOR, --monitor MONITOR
the monitor to screen shot
-o OUTPUT, --output OUTPUT
the output file name
-q, --quiet do not print created files
-v, --version show program's version number and exit
根据 @Arkadiusz Drabczyk 的非常有用的建议,我编写了一个有效的脚本。我想我会分享解决方案。
#!/bin/bash
# to have at most one instance of this script running...
script_name=${BASH_SOURCE[0]}
for pid in $(pidof -x $script_name); do
if [ $pid != $$ ]; then
kill -9 $pid
fi
done
loc="/path/to/folder/"
# take screenshots every minute starting at next minute...
s=$((60 - $(date +%-S)))
sleep "$s"s
while true
do
f=$(date +'%Y%m%d_%H%M%S')
scrot -q 20 "$f".jpg
n=$(xrandr --listmonitors | head -n 1 | sed -e "s/Monitors: //g")
if (( n == 2 )); then
convert -crop 1920x1080 +repage "$f".jpg "$f"_%d.jpg
mv -t "$loc" "$f"_0.jpg "$f"_1.jpg
rm "$f".jpg
else
mv -t "$loc" "$f".jpg
fi
s=$((60 - $(date +%-S)))
sleep "$s"s
done
备注:
- 上面的脚本比我最初要求的要多:
- 它确保此脚本的最多一个实例是 运行(第一个代码段),它是从评论中的 stack-overflow post. (As pointed out by @tripleee 借来的,这不是一个好的做法。请注意。)
- 使用一堆
sleep commands
从下一分钟开始每分钟截屏一次。如果您愿意,可以使用 cron-job handler 替换此功能。
- 上述问题的最小解是
convert -crop 1920x1090 +repage "$f".jpg "$f"_%d.jpg
。 (因此,如果您愿意,欢迎您去除这些肿块)。我添加了预期典型用法的额外位,以便人们可以按原样使用代码。
- 以下是其他操作的方法,如果您愿意:
- 您可以将
1920x1080
替换为左侧显示器的任何尺寸。您可以使用 xrandr -q | grep " connected"
. 找到这些维度
- 我的代码旨在用于固定设置,其中左侧显示器始终是
1920x1080
。欢迎您对其进行改进,使其适用于任何设置。
- 同样,我的代码适用于最多具有 2 个显示器的固定设置。再次欢迎您推广到任意数量的监视器。
- 如果您打算进行上述概括以便它适用于任何设置,请提一句忠告:是的,您需要
sed/awk/grep
或类似的方法来处理 xrandr -q
的输出。但请注意,xrandr -q
可以是慢步(如 here and here). However the output of xrandr -q
wouldn't change as often. So to make faster code, you could dump the output of xrandr -q
once, every time it's output would change and use the text from the dump for subsequent operations (as illustrated in this this answer 所述)以避免在每个循环中出现 运行 xrandr -q
。
希望对您有所帮助。干杯!
问题陈述
我使用 scrot
截取屏幕截图,除非我有多个监视器或显示器,否则效果很好。在这种情况下 scrot
将不同显示器的屏幕截图合并为一个输出。
根据联机帮助页,scrot
支持选项 -m
:
-m, --multidisp
For multiple heads, grab shot from each and join them together.
所以我想默认行为是 NOT 将它们连接在一起。然而,这种情况并非如此。即使没有 -m
选项,我也会加入屏幕截图。
我很乐观 scrot
应该能够做到这一点,因为它支持 -u
选项:
-u, --focused
Use the currently focused window.
效果很好。
我还查看了另一个名为 maim
的 CLI 工具 - 但我还是不知道如何分别截取不同显示器的屏幕截图。
所以我排除的解决方案应该像这样工作:
screenshot_command <display_name> # and other options
只截屏显示 <display_name>
。
我目前尝试的解决方案
maim
支持 curios looking 选项 -x
:
-x, --xdisplay=hostname:number.screen_number
Sets the xdisplay to use.
所以我尝试了 maim -x 0.0 | xclip -selection clipboard -t image/png
,但这不起作用。我不知道这个选项是如何使用的,因为没有足够的文档。
scrot
和maim
都支持选项-s
:
-s, --select
Interactively select a window or rectangle with the mouse.
所以我正在想象一个非常丑陋/骇人听闻的解决方案,使用xdotool
(或类似)到select所需的显示并使用选项-s
到 maim
或 scrot
可以完成这项工作。但我宁愿不走这条路,除非没有其他直接的解决方案。
胡思乱想
我想知道这个问题是否是因为我添加新显示器的方式?我通常使用如下命令添加我的第二个显示器:
xrandr --output eDP-1 --auto --output HDMI-1-4 --auto --right-of eDP-1
所以我想知道,可能是scrot
或maim
有只有一个显示。我想是因为 xdpyinfo | grep -A4 '^screen'
和 ONE 监视器的输出看起来像:
$ xdpyinfo | grep -A4 '^screen'
screen #0:
dimensions: 1920x1080 pixels (506x285 millimeters)
resolution: 96x96 dots per inch
depths (7): 24, 1, 4, 8, 15, 16, 32
root window id: 0x1ba
和 两个 显示器看起来像这样:
$ xdpyinfo | grep -A4 '^screen'
screen #0:
dimensions: 3280x1080 pixels (865x285 millimeters)
resolution: 96x96 dots per inch
depths (7): 24, 1, 4, 8, 15, 16, 32
root window id: 0x1ba
如果这确实是我出现问题的原因,那么我应该如何添加我的第二台显示器?
另一个解决方案是MSS。
安装非常简单(不需要昂贵的 Python 模块):
$ python3 -m pip install --user -U mss
它将添加一个新的 mss
可执行文件,您可以随时调用。
例如,要获取每台显示器的屏幕截图,只需键入:
$ mss
/home/USER/monitor-1.png
/home/USER/monitor-2.png
/home/USER/monitor-3.png
如果只想捕获第一个监视器:
$ mss --monitor 1
/home/USER/monitor-1.png
要在一张图片中捕获所有监视器的屏幕截图(如 scrot 所做的那样):
$ mss --monitor -1
/home/USER/monitor-0.png
截至目前,帮手显示:
$ mss --help
usage: mss [-h] [-c COORDINATES] [-l {0,1,2,3,4,5,6,7,8,9}] [-m MONITOR]
[-o OUTPUT] [-q] [-v]
optional arguments:
-h, --help show this help message and exit
-c COORDINATES, --coordinates COORDINATES
the part of the screen to capture: top, left, width,
height
-l {0,1,2,3,4,5,6,7,8,9}, --level {0,1,2,3,4,5,6,7,8,9}
the PNG compression level
-m MONITOR, --monitor MONITOR
the monitor to screen shot
-o OUTPUT, --output OUTPUT
the output file name
-q, --quiet do not print created files
-v, --version show program's version number and exit
根据 @Arkadiusz Drabczyk 的非常有用的建议,我编写了一个有效的脚本。我想我会分享解决方案。
#!/bin/bash
# to have at most one instance of this script running...
script_name=${BASH_SOURCE[0]}
for pid in $(pidof -x $script_name); do
if [ $pid != $$ ]; then
kill -9 $pid
fi
done
loc="/path/to/folder/"
# take screenshots every minute starting at next minute...
s=$((60 - $(date +%-S)))
sleep "$s"s
while true
do
f=$(date +'%Y%m%d_%H%M%S')
scrot -q 20 "$f".jpg
n=$(xrandr --listmonitors | head -n 1 | sed -e "s/Monitors: //g")
if (( n == 2 )); then
convert -crop 1920x1080 +repage "$f".jpg "$f"_%d.jpg
mv -t "$loc" "$f"_0.jpg "$f"_1.jpg
rm "$f".jpg
else
mv -t "$loc" "$f".jpg
fi
s=$((60 - $(date +%-S)))
sleep "$s"s
done
备注:
- 上面的脚本比我最初要求的要多:
- 它确保此脚本的最多一个实例是 运行(第一个代码段),它是从评论中的 stack-overflow post. (As pointed out by @tripleee 借来的,这不是一个好的做法。请注意。)
- 使用一堆
sleep commands
从下一分钟开始每分钟截屏一次。如果您愿意,可以使用 cron-job handler 替换此功能。 - 上述问题的最小解是
convert -crop 1920x1090 +repage "$f".jpg "$f"_%d.jpg
。 (因此,如果您愿意,欢迎您去除这些肿块)。我添加了预期典型用法的额外位,以便人们可以按原样使用代码。
- 以下是其他操作的方法,如果您愿意:
- 您可以将
1920x1080
替换为左侧显示器的任何尺寸。您可以使用xrandr -q | grep " connected"
. 找到这些维度
- 我的代码旨在用于固定设置,其中左侧显示器始终是
1920x1080
。欢迎您对其进行改进,使其适用于任何设置。 - 同样,我的代码适用于最多具有 2 个显示器的固定设置。再次欢迎您推广到任意数量的监视器。
- 如果您打算进行上述概括以便它适用于任何设置,请提一句忠告:是的,您需要
sed/awk/grep
或类似的方法来处理xrandr -q
的输出。但请注意,xrandr -q
可以是慢步(如 here and here). However the output ofxrandr -q
wouldn't change as often. So to make faster code, you could dump the output ofxrandr -q
once, every time it's output would change and use the text from the dump for subsequent operations (as illustrated in this this answer 所述)以避免在每个循环中出现 运行xrandr -q
。
- 您可以将
希望对您有所帮助。干杯!