В этой заметке хочу увековечить свой велосипед, который я изобрёл для удобного создания скриншотов. Да, я знаю о существовании таких программ как shutter, но все они по тем или иным причинам мне неудобны, а так как был интерес и время, я занялся этой проблемой.
Пользователь нажимает PrintScreen, появляется меню, в котором последовательно задаются вопросы:
Прорвавшись через эту кучу вопросов, программа:
Скрипт, вызванный без аргументов, будет каждый раз спрашивать вопросы заново. Однако, запомнив ответы пользователя, он их кеширует и записывает в файл (по умолчанию
Таким образом, настроив PrintScreen на вызов скрипта с загрузкой кеша, а Win+PrintScreen на вызов без загрузки кеша, я всегда могу изменить настройки, заново ответив на вопросы, после чего фотографировать дальше значительно быстрее.
Мой дистрибутив ArchLinux, и я пользуюсь openbox в качестве оконного менеджера. У счастливых обладателей KDE/Gnome/Xfce/ваш_вариант процесс установки и использования может отличаться.
Первые четыре программы должны быть (по идее) доступны в репозиториях вашего дистрибутива. Последний пункт опционален. Можете использовать другие шрифты, если terminus вам неугоден. Пятый пункт — моя собственная поделка, смысл которой сводится к заливке картинки на сайты типа ImageShack.us одной командой из командной строки. Сборка этого чуда, вообще говоря, не такая сложная, но описание этого процесса в любом случае выходит за рамки данной заметки, так что Вы вольны заменить этот компонент альтернативными решениями.
Вот как выглядела бы установка он начала до конца в моём дистрибутиве.
Установим стандартные пакеты:
Сообщим Иксам путь к этим шрифтам (плюс, хорошо бы прописать эту команду в ~/.xinitrc):
Считаем, что imagepaste (или аналог) уже установлен, поэтому пропускаем этот шаг.
Устанавливаем скрипт:
Папка ~/bin у меня используется для моих наколенных поделок. В скрипте Вы, вероятно, захотите изменить:
Не забудьте создать лог-файл:
И последнее, это повесить вызов скрипта на горячую клавишу. Я для этого использовал возможности openbox, а именно obkey для настройки горячих клавиш. Можно, впрочем, сразу залезть в ~/.config/openbox/rc.xml и добавить:
UPD 01: Добавлен выбор задержки: 0, 5, 10, 30, 60 секунд.
UPD 02: Добавлено: 1) кеширование ответов пользователя 2) возможность указать инкрементальный паттерн для имени файла.
Как работает мой велосипед
Пользователь нажимает PrintScreen, появляется меню, в котором последовательно задаются вопросы:
- Сохранить весь экран или только часть (окно)?
- Сохранить файл со снимком куда-то на долгую память или сохранить в ненадёжном /tmp?
- Ввести имя файла самому, сгенерировать случайное или генерировать по шаблону?
- Если по шаблону, предлагается выбрать шаблон или ввести его самому
- Выбрать задержку в секундах перед фотографированием
- Копировать ли URL опубликованной картинки в буфер
- Показать ли диалог с путём к файлу на диске, а также URL картинки
Прорвавшись через эту кучу вопросов, программа:
- Уточняет имя файла (если нужно)
- Делает скриншот экрана либо ждёт, пока пользователь выделит регион или окно (man scrot)
- Если пользователь ввёл имя файла, которое уже существует, выведется подтверждение на перезапись. В случае отмены пользователю придётся самому ещё раз вызвать скрипт (сам он пока не настолько умный, чтобы спросить другое имя файла)
- В лог-файл записывается путь к сохранённому файлу и URL опубликованной картинки
- В буфер обмена копируется URL скриншота (если надо)
- Отображается диалог с путём к файлу на диске и URL опубликованной картинки (если надо)
Скрипт, вызванный без аргументов, будет каждый раз спрашивать вопросы заново. Однако, запомнив ответы пользователя, он их кеширует и записывает в файл (по умолчанию
/tmp/screenshot.cache.sh
). Если запустить скрипт с аргументом cached
, скрипт попытается считать кешированные ответы, и если это удастся, задавать вопросы не будет.Таким образом, настроив PrintScreen на вызов скрипта с загрузкой кеша, а Win+PrintScreen на вызов без загрузки кеша, я всегда могу изменить настройки, заново ответив на вопросы, после чего фотографировать дальше значительно быстрее.
Disclaimer
Мой дистрибутив ArchLinux, и я пользуюсь openbox в качестве оконного менеджера. У счастливых обладателей KDE/Gnome/Xfce/ваш_вариант процесс установки и использования может отличаться.
Строительные материалы
- dmenu (показывать меню)
- scrot (скриншотер)
- zenity (спрашивать вопросы у пользователя)
- xclip (копировать ссылку в буфер обмена)
- imagepaste (заливать картинку на image hosting)
- скрипт (собрать все компоненты воедино)
- terminus-font (шрифты в меню, optional)
Первые четыре программы должны быть (по идее) доступны в репозиториях вашего дистрибутива. Последний пункт опционален. Можете использовать другие шрифты, если terminus вам неугоден. Пятый пункт — моя собственная поделка, смысл которой сводится к заливке картинки на сайты типа ImageShack.us одной командой из командной строки. Сборка этого чуда, вообще говоря, не такая сложная, но описание этого процесса в любом случае выходит за рамки данной заметки, так что Вы вольны заменить этот компонент альтернативными решениями.
Пошаговая инструкция
Вот как выглядела бы установка он начала до конца в моём дистрибутиве.
Установим стандартные пакеты:
$ pacman -S dmenu scrot zenity xclip terminus-font
Сообщим Иксам путь к этим шрифтам (плюс, хорошо бы прописать эту команду в ~/.xinitrc):
$ xset +fp /usr/share/fonts/local/
Считаем, что imagepaste (или аналог) уже установлен, поэтому пропускаем этот шаг.
Устанавливаем скрипт:
$ mkdir ~/bin
$ cd !$
$ wget https://bitbucket.org/balta2ar/screenshot/raw/45ad932db13b/screenshot.sh
$ chmod u+x ./screenshot.sh
Папка ~/bin у меня используется для моих наколенных поделок. В скрипте Вы, вероятно, захотите изменить:
LOG
— путь к лог-файлуFONT
— шрифт менюIMAGEPASTE_CMD
— команда для публикации картинкиBASEDIR
— базовая директория для тех скриншотов, которые вы захотите сохранятьНе забудьте создать лог-файл:
$ touch /var/log/screenshot.log
$ sudo chown `whoami`:users !$
И последнее, это повесить вызов скрипта на горячую клавишу. Я для этого использовал возможности openbox, а именно obkey для настройки горячих клавиш. Можно, впрочем, сразу залезть в ~/.config/openbox/rc.xml и добавить:
<keybind key="Print">
<action name="Execute">
<command>/home/bz/bin/screenshot.sh cached</command>
</action>
</keybind>
<keybind key="W-Print">
<action name="Execute">
<command>/home/bz/bin/screenshot.sh</command>
</action>
</keybind>
Плюсы
- своё не пахнет
- удобно, заточено под свои нужды
- автоматическая публикация
Минусы
- установка для красноглазых
- много компонентов, а хотелось бы один и чтобы всё работало искаропки
Скрипт целиком
#!/bin/bash
init()
{
ACTIONS[0]="window/region,screen"
ACTIONS[1]="drop,save"
ACTIONS[2]="create random,ask,incremental pattern"
ACTIONS[3]="screenshot-%05d.png"
ACTIONS[4]="0,5,10,30,60"
ACTIONS[5]="yes,no"
ACTIONS[6]="no,yes"
PROMPT[0]="Capture region"
PROMPT[1]="Picture file"
PROMPT[2]="File name"
PROMPT[3]="File name pattern"
PROMPT[4]="Delay"
PROMPT[5]="Copy to clipboard"
PROMPT[6]="Show links in a dialog"
IND_CAPTURE_REGION=0
IND_FILESAVE=1
IND_FILENAME=2
IND_PATTERN=3
IND_DELAY=4
IND_COPY_CLIPBOARD=5
IND_SHOW_LINKS=6
LOG="/var/log/screenshot.log"
FONT='-xos4-terminus-*-*-*-*-16-*-*-*-*-*-*-*'
DMENU="dmenu -fn $FONT"
IMAGEPASTE_CMD="imp"
SCREENSHOT_CMD="scrot"
SCREENSHOT_OPTIONS=
OPTIONS=
COUNT=${#ACTIONS[*]}
BASEDIR="/home/`whoami`/pic/screenshot/scrot"
CACHE="/tmp/screenshot.cache.sh"
PATTERN_INDEX=0
}
load_cache()
{
source $CACHE
}
save_cache()
{
echo -n > $CACHE
for (( i = 0; i < ${#OPTIONS[*]}; i++ ))
do
echo "OPTIONS[$i]=\"${OPTIONS[$i]}\"" >> $CACHE
done
echo "PATTERN_INDEX=\"$PATTERN_INDEX\"" >> $CACHE
}
random_filename()
{
TMP=`mktemp --suffix=.scrot`
BASE=`basename $TMP`
FILENAME="$BASEDIR/$BASE.png"
}
ask_filename()
{
FILENAME=`zenity --entry --text "Enter filename" --entry-text "$BASEDIR/"`
}
set_next_pattern_filename()
{
FILENAME="$BASEDIR/$(printf ${OPTIONS[$IND_PATTERN]} $PATTERN_INDEX)"
PATTERN_INDEX=$(($PATTERN_INDEX + 1))
while [ -e "$FILENAME" ]; do
FILENAME="$BASEDIR/$(printf ${OPTIONS[$IND_PATTERN]} $PATTERN_INDEX)"
PATTERN_INDEX=$(($PATTERN_INDEX + 1))
done
}
ask_options()
{
for i in $(seq 0 $(($COUNT - 1)))
do
# if we are about to ask patern and
# it wasn't the choise in prev question, continue
if [ "$i" -eq "$IND_PATTERN" -a "${OPTIONS[$IND_FILENAME]}" != "incremental pattern" ]
then
continue
fi
OP=`echo ${ACTIONS[$i]} | tr "," "\n" | $DMENU -p "${PROMPT[$i]}"`
if [ ! -n "$OP" ]; then
exit 0
fi
OPTIONS[$i]=$OP
done
}
parse_options()
{
# parse options and ask user questions, if any
ITEM=${OPTIONS[$IND_CAPTURE_REGION]}
case "$ITEM" in
window/region)
SCREENSHOT_OPTIONS="-b -s"
;;
screen)
;;
esac
ITEM=${OPTIONS[$IND_FILESAVE]}
case "$ITEM" in
save)
# Dont touch BASEDIR
;;
drop)
BASEDIR="/tmp"
;;
esac
ITEM=${OPTIONS[$IND_FILENAME]}
case "$ITEM" in
ask)
ask_filename
;;
"create random")
random_filename
;;
"incremental pattern")
set_next_pattern_filename
;;
esac
ITEM=${OPTIONS[$IND_DELAY]}
SCREENSHOT_OPTIONS="$SCREENSHOT_OPTIONS -d $ITEM"
}
check_existence()
{
if [ -e "$FILENAME" ]
then
zenity --question --text "File already exists. Overwrite?"
OVERWRITE=$?
if [ $OVERWRITE -ne 0 ]
then
exit 1
fi
fi
}
do_screenshot()
{
rm -f "$FILENAME"
mkdir -p `dirname "$FILENAME"`
$SCREENSHOT_CMD $SCREENSHOT_OPTIONS "$FILENAME"
CMD="$IMAGEPASTE_CMD $FILENAME"
URL="`$CMD`"
echo "$FILENAME -> $URL" >> $LOG
}
copy_to_clipboard()
{
if [ ${OPTIONS[$IND_COPY_CLIPBOARD]} == "yes" ]
then
echo "$URL" | xclip -selection primary
echo "$URL" | xclip -selection clipboard
fi
}
show_links()
{
if [ ${OPTIONS[$IND_SHOW_LINKS]} == "yes" ]
then
zenity --info --no-wrap --text "$FILENAME\n$URL"
fi
}
init
if [ -e "$CACHE" -a "$1" == "cached" ]
then
load_cache
else
ask_options
fi
save_cache
parse_options
check_existence
do_screenshot
copy_to_clipboard
show_links
exit 0
UPD 01: Добавлен выбор задержки: 0, 5, 10, 30, 60 секунд.
UPD 02: Добавлено: 1) кеширование ответов пользователя 2) возможность указать инкрементальный паттерн для имени файла.