Automatically take screenshot of specific display in X

multi-monitorscreenshotxorg

For creating a time lapse on a system running X with two screens (actually it's one "screen" on two "displays"), how do I take a screenshot of one of the screens?

xrandr output is (abbreviated):

Screen 0: minimum 320 x 200, current 3840 x 1080, maximum 16384 x 16384
DFP1 disconnected (normal left inverted right x axis y axis)
DFP2 disconnected (normal left inverted right x axis y axis)
DFP3 disconnected (normal left inverted right x axis y axis)
DFP4 disconnected (normal left inverted right x axis y axis)
DFP5 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 598mm x 336mm
   1920x1080     60.00*+  50.00    59.94    50.00    60.00    59.94  
   [...]
DFP6 disconnected (normal left inverted right x axis y axis)
DFP7 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 598mm x 336mm
   1920x1080     60.00*+  50.00    59.94    50.00    60.00    59.94  
   [...]
CRT1 disconnected (normal left inverted right x axis y axis)

Requirements:

  1. Minimal overhead
  2. Desktop environment agnostic
  3. Automatic
  4. Screen selected by name

1, 2 and 3 mean that the tool would ideally run in the command line.

Best Answer

ImageMagick's import can take a screenshot of Xorg's root automatically and with -crop only the wanted part will be used. xrandr provides the parameter for crop.

To minimize overhead, you should construct the import command once rather than querying using the display name each time you take a screenshot:

mapfile -t displays < <(xrandr | grep ' connected')
get_date='`date +"%Y%m%d-%H%M%S"`'
for (( i=0; i<${#displays[@]}; i++)); do
  name=`echo ${displays[i]} | cut -d " " -f 1`
  crop=`echo ${displays[i]} | cut -d " " -f 3`
  echo import -silent -window root -crop ${crop} \"${name}-${get_date}.png\"
done

Explanation of the mapfile and for loop can be found in this question.

This will give you commands like the following:

import -silent -window root -crop 1920x1080+0+0 "DFP5-`date +"%Y%m%d-%H%M%S"`.png"
import -silent -window root -crop 1920x1080+1920+0 "DFP7-`date +"%Y%m%d-%H%M%S"`.png"

which you can now use in a while loop for your timelapse (stop with ctrl+c).

while [ 1 ]; do
  import ...
  sleep 1 # for 1 second delay between screenshots
done

This is the only method I know. Hopefully there are ways with less overhead.

Related Question