viewer2grabs.sh

A script that will grab a series of screenshots of any viewer application window that can be controlled by key presses (e.g., Evince, Foliate, …).

Requires:

  • convert, identify, import imagemagick
  • xdotool xdotool

The script controls the viewer application by sending virtual key presses:

  • It makes the viewer app go fullscreen at the beginning;
  • grabs a screenshot;
  • sends the appropriate key press to make the viewer advance by one page;
  • before grabbing the next screenshot.

How to call it (after starting it, you have a few seconds to bring the viewer application window to the front):

viewer2grabs.sh -n numberOfPages -p pageDownKey -f fullscreenKey -g secsBeforeFirstGrab -b secsBetweenPages

E.g.:

viewer2grabs.sh -n 7 -p Page_Down -f F11 -g 2.0 -b 1.0

You’ll most likely want to post-process the screenshots by calling grabs2pdf.sh.

To download this script, first hover with your mouse over the listing below and press »Open code in new window«. Copying and pasting the colored and formatted listing below, as-is, won’t work.
#!/bin/bash

# You can increase secs_before_first_grab and secs_between_pages if viewer application needs more time to render a page.

# Usage:
# 1. Open document in viewer application, move to desired first page
# 2. Call viewer2txt.sh
#    viewer2grabs.sh -n numberofpages -p pagedownkey -f fullscreenkey -g secsbeforfirstgrab -b secsbetweenpages
#    e.g.: viewer2grabs.sh -n 7 -p Page_Down -f F11 -g 2.0 -b 1.0
# 3. You have a few seconds to activate (bring to front) the window of the viewer application

num_of_pages=1
page_down_key=Page_Down # common values: Page_Down; Down; n; ...
full_screen_key=F11 # common values: F11; ctrl+shift+F; ...
secs_before_first_grab=2.0
secs_between_pages=0.5

while getopts ":n:p:f:g:b:" opt; do
  case $opt in
    n) num_of_pages="$OPTARG"
    ;;
    p) page_down_key="$OPTARG"
    ;;
    f) full_screen_key="$OPTARG"
    ;;
    g) secs_before_first_grab="$OPTARG"
    ;;
    b) secs_between_pages="$OPTARG"
    ;;
    \?) echo "Invalid option -$OPTARG" >&2
    echo "Usage:" >&2
    echo "$(basename $0) [-n numberOfPages] [-p pageDownKey] [-f fullscreenKey] [-g secsBeforeFirstGrab] [-b secsBetweenPages]"
    echo
    echo "Examples:"
    echo "$(basename $0)"
    echo "$(basename $0) -n $num_of_pages"
    echo "$(basename $0) -n $num_of_pages -p $page_down_key -f $full_screen_key -g $secs_before_first_grab -b $secs_between_pages"
    exit 1
    ;;
  esac
done
shift $((OPTIND-1))

echo "Executing: $(basename $0) -n $num_of_pages -p $page_down_key -f $full_screen_key -g $secs_before_first_grab -b $secs_between_pages"


# No config beyond this point.
GRABBED_SCREENS_DIR=./screens
ACTIVATION_GRACE_PERIOD_SECS=10.0

# Provide empty directory for grabbed screens
mkdir -p "$GRABBED_SCREENS_DIR"
rm "$GRABBED_SCREENS_DIR"/grabbed-*.png

# Wait a few secs, then determine ID of active window, and make it full screen
my_window_id=$(xdotool getactivewindow)
echo You have $ACTIVATION_GRACE_PERIOD_SECS seconds to bring the viewer\'s window to the front.
viewer_window_id=$(sleep $ACTIVATION_GRACE_PERIOD_SECS; xdotool getactivewindow)
if [ "$my_window_id" = "$viewer_window_id" ]; then
    echo You need to bring the viewer\'s window to the front.
    echo Aborting.
    exit 1
fi

echo Grabbing $num_of_pages pages now...

xdotool key --clearmodifiers $full_screen_key
sleep $secs_before_first_grab

# Fore every page: grab it, move viewer to next page, and wait secs_between_pages
for (( current_page=1; current_page<=$num_of_pages; current_page++ ))
do
    suffix=$(printf "%04d" $current_page)
    echo Screen grabbing page $current_page of $num_of_pages...

    import -window $viewer_window_id -density 300 "$GRABBED_SCREENS_DIR"/grabbed-$suffix.png
    xdotool key --clearmodifiers $page_down_key
    sleep $secs_between_pages
done
xdotool key --clearmodifiers $full_screen_key


first_grab="$GRABBED_SCREENS_DIR"/grabbed-0001.png
sample_crop="$GRABBED_SCREENS_DIR"/please_crop_me.png

GRABBED_WIDTH=$(identify -format '%w' "$first_grab")
GRABBED_HEIGHT=$(identify -format '%h' "$first_grab")
echo
echo Finished grabbing $num_of_pages pages from viewer.
echo Screen grabs are ${GRABBED_WIDTH}x${GRABBED_HEIGHT} pixels.

convert -quality 100 -density 300 "$first_grab" "$sample_crop" # Create sample crop page

echo
echo As an example for me, please crop $sample_crop, using your favorite bitmap editor.
echo The result must show the page region only. Then, run grabs2pdf.sh and
echo I will crop all grabbed pages, following your example.

Image Credits:
Papirus icon for Terminal (modified) | GNU General Public License, version 3

Licensing:
This content is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
For your attributions to us please use the word »tuxwise«, and the link https://tuxwise.net.