Home

Awesome

shotgun

A minimal screenshot utility for X11. Shotgun was written to replace maim in my workflow.

Features:

Installation

Packaging status

From source:

Usage

Usage: shotgun [options] [file]

Options:
    -i, --id ID         Window to capture
    -g, --geometry WxH+X+Y
                        Area to capture
    -f, --format png/pam
                        Output format
    -s, --screen        Capture the current screen
    -h, --help          Print help and exit
    -v, --version       Print version and exit

Examples

To use with hacksaw: take a screenshot and copy to clipboard

#!/bin/sh -e

selection=$(hacksaw -f "-i %i -g %g")
shotgun $selection - | xclip -t 'image/png' -selection clipboard

To use with slop (as a replacement for maim -s):

#!/bin/sh -e

sel=$(slop -f "-i %i -g %g")
shotgun $sel "$1"

shotgun vs maim

There are several reasons for omitting these features:

Performance

I've claimed that shotgun is twice as fast as maim, here's some supporting evidence (using hyperfine):

$ xrandr --fb 3840x2160
$ hyperfine --warmup 15 --min-runs 50 \
>     'maim > /dev/null' \
>     'shotgun - > /dev/null'
Benchmark #1: maim > /dev/null
  Time (mean ± σ):     629.3 ms ±   3.7 ms    [User: 570.7 ms, System: 52.1 ms]
  Range (min … max):   624.8 ms … 646.7 ms    50 runs

Benchmark #2: shotgun - > /dev/null
  Time (mean ± σ):     293.0 ms ±   3.2 ms    [User: 239.6 ms, System: 52.9 ms]
  Range (min … max):   287.8 ms … 298.2 ms    50 runs

Summary
  'shotgun - > /dev/null' ran
    2.15 ± 0.03 times faster than 'maim > /dev/null'

Further profiling has shown that the bottleneck in shotgun lies fully within the PNG encoder.

Going faster

The PNG encoder bottleneck can be avoided by using -f pam. This sets the output format to Netpbm PAM - an uncompressed binary image format.

By using an uncompressed format both encoding and decoding performance is improved:

Encoding

$ hyperfine --warmup 15 --min-runs 50 \
>     'shotgun -f png - > /dev/null' \
>     'shotgun -f pam - > /dev/null'
Benchmark #1: shotgun -f png - > /dev/null
  Time (mean ± σ):     294.5 ms ±   3.3 ms    [User: 240.0 ms, System: 54.1 ms]
  Range (min … max):   289.2 ms … 301.4 ms    50 runs

Benchmark #2: shotgun -f pam - > /dev/null
  Time (mean ± σ):     116.8 ms ±   2.8 ms    [User: 62.5 ms, System: 53.7 ms]
  Range (min … max):   113.8 ms … 122.7 ms    50 runs

Summary
  'shotgun -f pam - > /dev/null' ran
    2.52 ± 0.07 times faster than 'shotgun -f png - > /dev/null'

Decoding (using ImageMagick to convert to jpg)

$ hyperfine --warmup 15 --min-runs 50 \
>     'shotgun -f png - | convert - jpg:- > /dev/null' \
>     'shotgun -f pam - | convert - jpg:- > /dev/null'
Benchmark #1: shotgun -f png - | convert - jpg:- > /dev/null
  Time (mean ± σ):     600.7 ms ±   5.8 ms    [User: 506.4 ms, System: 96.5 ms]
  Range (min … max):   594.9 ms … 620.7 ms    50 runs

Benchmark #2: shotgun -f pam - | convert - jpg:- > /dev/null
  Time (mean ± σ):     350.4 ms ±   3.9 ms    [User: 217.0 ms, System: 139.3 ms]
  Range (min … max):   345.5 ms … 367.8 ms    50 runs

Summary
  'shotgun -f pam - | convert - jpg:- > /dev/null' ran
    1.71 ± 0.03 times faster than 'shotgun -f png - | convert - jpg:- > /dev/null'