Выбрать главу

Получили?

Возможно, вам станет понятнее после разбора практического примера. Именно эту цель преследует функция usage() в сценарии, представленном в листинге 14.5.

Код

Листинг 14.5. Сценарий frameit

··#!/bin/bash

··# frameit — упрощает добавление графической рамки вокруг

··#·· изображения, используя ImageMagick.

··usage()

··{

··cat << EOF

··Usage: $(basename $0) −b border −c color imagename

····or $(basename $0) −f frame −m color imagename

··In the first case, specify border parameters as size x size or

··percentage x percentage followed by the color desired for the

··border (RGB or color name).

··In the second instance, specify the frame size and offset,

··followed by the matte color[8].

··

··EXAMPLE USAGE:

····$(basename $0) −b 15x15 −c black imagename

····$(basename $0) −b 10%x10 % −c gray imagename

····$(basename $0) −f 10x10+10+0 imagename

····$(basename $0) −f 6x6+2+2 −m tomato imagename

··EOF

··exit 1

··}

··#### ГЛАВНЫЙ БЛОК КОДА

··# Большая его часть занимается парсингом начальных аргументов!

··while getopts "b: c: f: m: " opt; do

····case $opt in

······b) border="$OPTARG";······;;

······c) bordercolor="$OPTARG";;;

······f) frame="$OPTARG";······;;

······m) mattecolor="$OPTARG";··;;

······?) usage;················;;

····esac

··done

··shift $(($OPTIND — 1)) # Употребить все проанализированные аргументы.

··if [$# −eq 0]; then # Изображения не указаны?

····usage

··fi

··# Что требуется добавить? Бордюр или рамку?

··if [! -z "$bordercolor" −a! −z "$mattecolor"]; then

····echo "$0: You can't specify a color and matte color simultaneously." >&2

····exit 1

··fi

··if [! -z “$frame” −a! −z “$border”]; then

····echo “$0: You can’t specify a border and frame simultaneously.” >&2

····exit 1

··fi

··if [! -z “$border”]; then

····args=”-bordercolor $bordercolor −border $border”

··else

····args=”-mattecolor $mattecolor −frame $frame”

··fi

··for name

··do

····suffix="$(echo $name | rev | cut −d. -f1 | rev)"

····prefix="$(echo $name | rev | cut −d. -f2- | rev)"

····newname="$prefix+f.$suffix"

····echo "Adding a frame to image $name, saving as $newname"

····convert $name $args $newname

··done

··exit 0

Как это работает

Если не считать использования команды getopts для анализа сложных параметров, которую мы уже исследовали, этот сценарий действует достаточно прямолинейно. Основная работа в нем выполняется в нескольких последних строках. В цикле for создается имя нового файла, включающее "+f" в конце (но перед расширением, определяющим тип файла).

Например, для имени файла abandoned-train.png в переменную suffix будет записано расширение png, а в переменную prefix — имя abandoned-train. Обратите внимание на пропажу точки (.) — она возвращается на место во время сборки нового имени файла . После этого остается только вызвать программу convert со всеми параметрами .

Запуск сценария

Укажите тип желаемой рамки — с помощью параметра −frame (для придания 3-мерного вида) или −border (простой бордюр) — и ее размеры, предпочтительный цвет для бордюра или лицевой поверхности рамки, а также имя исходного файла (или файлов). Например, как показано в листинге 14.6.

Листинг 14.6. Запуск сценария frameit

$ frameit −f 15%x15 %+10+10 −m black abandoned-train.png

Adding a frame to image abandoned-train.png, saving as abandoned-train+f.png

Результаты

Результат этого вызова показан на рис. 14.2.

Рис. 14.2. 3-мерная рамка матового стекла в музейном стиле

Усовершенствование сценария

Если забыть указать один из параметров, ImageMagick выведет типичное туманное сообщение:

$ frameit −f 15%x15 %+10+10 alcatraz.png

Adding a frame to image alcatraz.png, saving as alcatraz+f.png

convert: option requires an argument '-mattecolor’ @ error/convert.c/

ConvertImageCommand/1936.

Добавление в сценарий дополнительных проверок на возможные ошибки, чтобы оградить пользователя от подобной абракадабры, стало бы неплохим усовершенствованием, как вы думаете?

Этот сценарий может неправильно работать с файлами, если их имена содержат пробелы. Конечно, пробелов вообще не должно быть в именах файлов, которые используются веб-сервером, тем не менее, вам стоило бы исправить сценарий, чтобы устранить этот недостаток.

вернуться

8

В первом случае определяются параметры бордюра, как пиксели×пиксели или проценты×проценты, за которыми следует желаемый цвет бордюра (в формате RGB или в виде названия цвета).

Во втором случае определяются размеры рамки и ее фасок, за которым следует цвет рамки.