Часто ли вам приходится работать с графикой? Как часто вы сталкиваетесь с недостатком стандартных эффектов/плагинов для обработки изображений? А можете ли вы, комбинируя доступные эффекты, получать требуемый результат? Если Вы утвердительно отвечаете на эти вопросы эта статья для Вас!
К счастью, сегодня существует достаточное количество программных пакетов для обработки графики. Это Corel Draw, Photoshop, The GIMP, Paint Shop Pro и т. д. Этот список можно продолжать до бесконечности. Лично мне больше всего нравится The GIMP (GNU Image Manipulation Program). Он достаточно функционален, удобен (во всяком случае для меня) в использовании и, самое главное, легко автоматизируется и бесплатен!
В The GIMP (далее просто GIMP) реализован язык сценариев Script-FU, который, собственно, и позволяет автоматизировать обработку/создание изображений. С его помощью реализована почти сотня (!) эффектов, включенных в стандартную поставку GIMP. Этот язык прост и эффективен одновременно. О нем и пойдет речь в данной статье.
Хочу заметить, что самому языку я вас учить не буду, а лишь покажу один из возможных путей его САМОСТОЯТЕЛЬНОГО освоения. Я убежден, что лучшим методом изучения чего-либо является самостоятельная ПРАКТИЧЕСКАЯ работа над примерами, примерами и еще раз примерами.
Недавно мне понадобился эффект для имитации состарившейся бумаги. Его, как такового, я не нашел, но смог воплотить его (приближенно) в жизнь, комбинируя доступные. Чтобы его повторить, мне пришлось потратить больше минуты. Тогда я и решил, что будет легче создать соответствующий сценарий, чем выполнять рутинную работу несколько раз! В данной статье я покажу, как я осваивал язык сценариев.
Итак, поставим задачу так: необходимо составить сценарий для имитации старения бумаги. В GIMP оказалось возможным достичь подобного эффекта (Рис. 1) с помощью трех эффектов: применяем холст, наносим кофейное пятно, применяем эффект старого фото. Первое, что нас не устраивает пятна кофе круглые (нужна прямоугольная их форма); второе они появляются в случайных местах; третье нам вовсе не нужно несколько пятен достаточно и одного.
Я подразумеваю, что мы работаем в Линуксе. Также подразумевается, что у вас достаточные познания GIMP'a и английского, т. е. увидь что-нибудь вроде gimp-gradients-set-active, вы поймете, что эта операция устанавливает рабочий (активный) градиент и знаете (хоть и примерно) где находится (если конечно находится) эта операция в меню. Желательно знание какого-нибудь языка программирования (Pascal, C).
Итак, начнем вносить соответствующие коррективы. В каталоге /usr/share/gimp/номер_версии/scripts/ находятся стандартные сценарии GIMP'а. Ищем coffee.scm и копируем его в каталог .gimp/scripts (в своем домашнем каталоге). Далее создаем его копию с именем old_paper.scm.
Настало время заглянуть в сценарий и проанализировать его. По пути я буду его комментировать. Замечу лишь, что строки, начинающиеся с ";" считаются комментариями. Также комментарии все то, что находится за ";" в строках (но не в строковых константах).
В этой «шапке» нет полезной информации только лишь указывается авторство и условия распространения (GNU License).
Здесь объявляется функция script-fu-coffee-stain с аргументами inImage (исходное изображение), inLayer (рабочий слой), inNumber (количество пятен) и inDark (эффект «замена темным»).
оператор set! объявляет переменную old-gradient и присваивает ей значение, возвращаемое функцией gimp-gradients-get-active. Вызов функции выполняется с помощью оператора car. Следует заметить, что все выражения (и вызовы функций) должны быть заключены в скобки. Все выражения оформляются следующим образом:
Это эквивалентно следующей записи, к примеру, на Паскале:
Например, (set! old-gradient (car (gimp-gradients-get-active))) на Паскале может быть записано так: old_gradient:=gimp_gradients_get_active; (а может быть и так: old_gradient:=gimp.gradients.get_active;)
Итак, мы немного узнали о внутреннем строении сценариев в GIMP'e. Следующий шаг модифицируем этот сценарий для наших нужд.
Первое, что изменяем это заголовок объявления нашей функции:
здесь новые параметры:
InBorder ширина "порванной" рамки в пикселях;
inCanvas надо ли делать бумагу рельефной (TRUE или FALSE)
InDirection направление падения света на рельеф
inDeep глубина рельефа
Далее добавляем переменную theTime и присваиваем ей значение inTime:
Добавляем размеры «по иксу» и «по игреку» (лишь для удобства):
Убираем цикл (while) ведь нам надо одно «пятно».
Изменяем конструктор слоя theStain так, чтобы он создавался не пустым, а с копией исходного изображения:
Теперь самое время поговорить о том, где можно брать названия и параметры вызова функций. Как было сказано выше, изучать мы будем САМОСТОЯТЕЛЬНО. С самим GIMP'ом не поставляется справка о языке сценариев. Поэтому будем выкручиваться сами . Брать информацию о функциях лучше всего в самих же сценариях! Открываете любой сценарий и смотрите, какие функции вызываются. Следует обращать внимание на структуру их названий. Это очень важно, потому что по аналогии можно составить имя предполагаемой функции (и выполнить в сценариях ее поиск большая вероятность, что такая найдется, еще и с примером использования :-)). Это что касается сценариев Scriop-FU.
Плагины же поставляются без исходных текстов и для того, чтобы ознакомится с информацией по интересующему плагину, надо найти его в файле pluginrc в каталоге .gimp-номер_версии/ в вашем домашнем каталоге. Например, нам необходим плагин Apply Canvas (Применить Холст). Ищем. Смотрим:
Здесь нас интересует точное название (plug_in_apply_canvas), а также количество, назначение и тип аргументов (по умолчанию используются целые числа). В данном примере:
(proc-arg 0 "run_mode""Interactive, non-interactive") режим запуска: (интерактивный, с диалоговым окном) = 0, неинтерактивный (как раз для нас) = 1);
(proc-arg 13 "image""Input image (unused)") исходное изображение (только для чтения);
(proc-arg 16 "drawable""Input drawable") изображение, которое будет модифицироваться;
(proc-arg 0 "direction""Light direction (0 3)") направление падения света и его диапазон (0 3);