В данный момент вы не в системе. Авторизируйтесь при помощи следующей формы. Замечание: для работы у вас должны быть включены cookies.
У вас еще нет аккаунта? Извольте получить: Зарегистрироваться
Это руководство написано для GIMP версии 1.1.24. Некоторые вещи, описанные сдесь, могут не работать или работать не так, как с GIMP 1.0.x.
Это короткое руководство по программированию в скрипт-фу. Я попытаюсь дать некое представление о мире скрипт-фу и обьяснить работу основных вещей. Сдесь шаг за шагом мы сделаем рабочий скрипт. Наша цель - это сделать скрипт, результатом работы которого, является текст в стиле metal. Я предполагаю, что читатель имеет базовые знания языка схем, который используется в скрипт-фу.
Хорошо, сейчас мы сделаем первый шаг, решим, что мы хотим выполнить в скрипте. И выполним это в GIMP обычным методом. Это важно, знать конкретно, какие операции мы должны выполнить, и в каком порядке.
Итак, давайте создадим наше пробное изображение. Пежде всего созданим новое цветное (RGB) изображение (<Файл> “Новый”) и вставим в него какой-нибудь текст, скажем слово “TEST”.
Затем мы скопируем текст и применим градиент металла на верхний слой.
Следующим нашим шагом будет создание нового слоя с тем же текстом, но немного больше. Для этого мы используем функцию “Альфа-канал → Выделенная область”, увеличиваем выделение на несколько пикселей и применяем тот же градиент, но с другой ориентацией (прим. перев: с включеной опцией градиента “Перевернуть”)
И на последок мы соединяем слои и применяем стандартную падающую тень. Когда все это проделано, мы авто-кадрируем изображение и удаляем неиспользуемые части.
Хорошо, сейчас изображение выглядит так, как мы и хотели. Давайте подведем итоги того, что нужно сделать:
Теперь наша задача состоит в том, чтобы воспроизвести все это в консоли Скрипт-Фу: где Вы можете вводить команды и проверять их. Используйте также консоль для проверки незнакомых Вам функций; в консоли Вы можете производить диагностику Ваших скриптов. Лучше всего, если Вы будете проверять каждую строчку скрипта сначала в консоли, а затем уже записывать в файл.
Для этого мы открываем консоль (<Расш.> “Скрипт-Фу” → “Консоль Скрипт-Фу”). Когда откроется консоль жмем на кнопочку “Просмотр...”, она находится внизу справа; после этого появится окно списка процедур, где Вы можете найти функции доступные из скриптов. Также с именами функций Вы можете получить описание передаваемых аргументов и общее описание действий функции.
Пришло время воспроизвести наш первый шаг - создание изображения, для этого нам нужна функция создания изображения. Большинство функций в окне списка функций имеют имена соответсвующие пути/именам в меню GIMP. После небольшого поиска по слову “new”, мы находим функцию “gimp-image-new”, это то, что нам нужно. Вводим следующее в консоль:
(gimp-image-new 256 256 RGB)
И вот, что мы увидим:
=> (gimp-image-new 256 256 RGB) (3)
Первая строчка - это просто команда, которая выполнилась. Вторая - это значение, которое возвратила функция. Как Вы можете прочитать в окне списка процедур, это так называемое id только что созданного изображения. Вы можете использовать этот id в качестве аргумента другим функциям в консоли. Возвращаемое значение - это также первый подводный камень на нашем пути изучения Скрипт-Фу. Дело в том, что значения функции возвращаются списком, а не целым значением. Поэтому, чтобы использовать это значение, мы должны взять первый элемент списка с помощью функции “car”.
Сейчас Вы наверное удивлены, где же изображение, которые мы только что создали? Ответ очень прост: мы не создали экрана для него, т.е. изображение находится только в памяти. Итак, создадим экран для нашего изображения. Однако, во время выполнения команды “(gimp-display-new 3)”, мы получаем ошибку:
ERROR: Procedural database execution failed: (gimp_display_new 3)
Не волнуйтесь, это просто очередной подводный камень. Не все функции в Скрипт-Фу выполняют теже действия, что и их аналоги в меню. Иногда, они просто работают на более низком уровне, поэтому Вы должны проделать немного больше работы, для получения нужных результатов. Проблема в том, что созданное изображение не имеет слоев. Для вывода изображения, нам нужен хотя бы один слой. Итак, следующим шагом будет создание нового слоя:
=> (gimp-layer-new 3 256 256 RGB-IMAGE "foobar" 100 NORMAL-MODE) (21)
Вы наверное заметили, что константы RGB-IMAGE и NORMAL-MODE, обозначены как RGB_IMAGE и NORMAL_MODE в окне списка процедур (с нижним подчеркиванием ‘_’). В Скрипт-Фу Вы должны заменить все символы нижнего подчеркивания (’_’) на минус (’-’). Если Вы не уверены в правильности замены, просто проверьте себя, введя эту константу в консоли Скрипт-Фу.
Следующим нашим шагом будет добавление созданного слоя к изображению, как написано в окне списка процедур:
=> (gimp-image-add-layer 3 21 -1) ()
И наконец мы можем отобразить изображение:
=> (gimp-display-new 3) (4)
Появившееся изображение выглядит несколько жутковато, это потому, что залито случайными цветами. Для того, чтобы очистить его, зальем слой цветом текущего заднего плана.
=> (gimp-drawable-fill 21 BG-IMAGE-FILL) ()
Функция для заливки слоя называется “gimp-drawable-fill”, не “gimp-layer-fill”, как Вы могли подумать. Это потому, что слой является обьектом рисования. Поэтому, если Вам нужно найти функцию для манипуляции слоями - посмотрите также в функции манипуляции обьектами рисования.
Теперь у нас есть изображение. Быстро для Вас? Давайте подведем итоги и напишем нашу первую функцию. Для начала мы инкапсулируем все действия в блок “let*”, а потом добавим наш блок в тело функции.
(define (my-make-new-image) (let* ((image (car (gimp-image-new 256 256 RGB))) (layer (car (gimp-layer-new image 256 256 RGB-IMAGE "foobar" 100 NORMAL-MODE)))) (gimp-drawable-fill layer BG-IMAGE-FILL) (gimp-image-add-layer image layer 0) (gimp-display-new image) image))
Последняя строка функции - это возвращаемое значение, т.е. наша функция возвращает значение image.
Итак, вернемся к нашей идее обработки текста, для этого нам нужно добавить строку на изображение и обработать ее. Небольшой поиск выдает нам функцию “gimp-text-fontname”. Для ее вызова мы набираем:
=> (gimp-text-fontname 3 21 -1 0 "Foobar" 0 TRUE 25 PIXELS "-freefont-blippo-heavy-r-normal-*-24-*-*-*-p-*-iso8859-1") (33)
И вот у нас уже есть наш текст на недавно созданном слое. Строка “-freefont-blippo-heavy-r-normal-*-24-*-*-*-p-*-iso8859-1” наверное выглядит для вас как заклинание, но позже мы рассмотрим простой путь для составления таких строк.
Теперь нам нужно продублировать слой, Вы наверное обратили внимание на то, что в списке функций нет функции для дублирования слоев. Поэтому нам нужно сделать это самим, а лучше напишем для этого еще одну функцию:
(define (my-duplicate-layer image layer) (let* ((dup-layer (car (gimp-layer-copy layer 1)))) (gimp-image-add-layer image dup-layer 0) dup-layer))
И потом:
=> (my-duplicate-layer 3 34) 41
Следующий шаг - это добавление некоторого количества пустого места для увеличения границы текста, сдесь нам поможет “gimp-layer-resize”:
(gimp-layer-resize 41 200 100 5 5)
Это работает, но ширина и высота жестко запрограммированы, поэтому давайте сделаем это более гибко:
(define (my-layer-add-border layer border) (let* ((width (car (gimp-drawable-width layer))) (height (car (gimp-drawable-height layer)))) (gimp-layer-resize layer (+ width border) (+ height border) (/ border 2) (/ border 2))))
Сейчас нам нужно сделать над слоем операцию “Альфа-канал → Выделенная область” и увеличить выделение на несколько пикселей:
(gimp-selection-layer-alpha 41) (gimp-selection-grow 3 5)
Перед тем, как залить слой, нужно снять флажок “Сохранять прозрачность”, который означает, что все прозрачные части остаются прозрачными:
(gimp-layer-set-preserve-trans 41 0)
Теперь заливаем выделенную область градиентом:
(gimp-blend 41 CUSTOM NORMAL LINEAR 100 0 REPEAT-NONE FALSE 0 0 0 0 30 50)
Вот теперь у нас есть все для написания скрипта, только нужно соеденить в нужной последовательности все части. В следующих шагах мы также удалим некоторые ненужные действия.
Хорошо, теперь определимся, как писать скрипты? Нам нужно знать три основные вещи. Первое, файл в который Вы пишите скрипт, должен находиться в каталоге ~/gimp-’версия GIMP’/scripts. Второе - нам понадобится отдельная функция, которая выполняет все манипуляции с изображением. И третье - Вам нужно сделать вызов функции “script-fu-register”, для того, чтобы Ваш скрипт был доступен из меню GIMP.
Ладно, давайте напишим пустую функцию и зарегистрируем ее в GIMP. Вы должны скопировать и вставить следующий код в файл dummy.scm и сохранить его в каталоге ~/gimp-’версия GIMP’/scripts/ как написано выше.
(define (my-dummy-function a b) (print "Do nothing")) (script-fu-register "my-dummy-function" _"<Toolbox>/Xtns/Script-Fu/My Stuff/Dummy..." "Do nothing" "Joey User" "Joey User" "August 2000" "" SF-ADJUSTMENT _"Width" '(400 1 2000 1 10 0 1) SF-ADJUSTMENT _"Height" '(30 1 2000 1 10 0 1))
Когда Вы запустите <Расш.> “Скрипт-Фу” → “Обновить скрипты”, Ваш скрипт загрузится в GIMP и будет доступен из меню (прим. перев.: <Расш.> “Скрипт-Фу” → “My Stuff” → “Dummy”).
Примечание: есть два типа скриптов. Первый тип создает новое изображение, они используются для создания логитипов и доступны из меню <Расш.> “Скрипт-Фу” → “...”. И второй тип, скрипты, которые работают с уже существующими изображениями, эти скрипты доступны из меню окна изображения <Скрипт-Фу> “...”. Для регистрации воторого типа скриптов Вам нужно указать такой путь: <Image>/Script-Fu/... и таким скриптам должны передаваться в качестве первых двух аргументов переменные следующих типов: SF-IMAGE и SF-DRAWABLE.
И вот мы подошли к следующей теме: аргументы, которые могут получать Ваши функции, могут быть следующих типов:
| Тип аргумента | Тип данных | Описание |
| SF-IMAGE | Integer (image id) | Используется для получения id изображения |
| SF-DRAWABLE | Integer (drawable id) | Используется для получения id обьекта |
| SF-VALUE | String | Входящее числовое значение |
| SF-TOGGLE | Boolean (TRUE or FALSE) | Входящее логическое значение |
| SF-PATTERN | String (Pattern name) | Позволяет Вам выбрать шаблон |
| SF-ADJUSTMENT | List (start-value min-value max-value small-step large-step [int=0 or float=1] [slider=0 or roll-box=1]) | Создает бегунок или диалог ввода с указанными значениями |
| SF-FILENAME | String (pathname) | Позволяет Вам найти файл |
| SF-STRING | String | Создает поле ввода |
| SF-FONT | String (fontname) | Позволяет Вам выбрать шрифт |
| SF-COLOR | List (red green blue) [0-255] | Позволяет Вам выбрать цвет |
| SF-OPTION | List of strings | Позволяет Вам выбрать пункт меню |
| SF-GRADIENT | String (gradient name) | Позволяет Вам выбрать градиент |
Следующий код создает диалог со всеми возможными полями ввода:
(define (my-demo-box value adj1 adj2 image drawable toggle pattern string font color option gradient) (print "Do nothing")) (script-fu-register "my-demo-box" "<Toolbox>/Xtns/Script-Fu/My Stuff/Demo Box..." "Do nothing" "Joe User" "Joe User" "August 2000" "" SF-ADJUSTMENT "SF-ADJUSTMENT (slider)" '( 30 1 2000 1 10 1 0) SF-ADJUSTMENT "SF-ADJUSTMENT" '(400 1 2000 1 10 1 1) SF-COLOR "SF-COLOR" '(255 0 255) SF-DRAWABLE "SF-DRAWABLE" 0 SF-FONT "SF-FONT" "" SF-GRADIENT "SF-GRADIENT" "Golden" SF-IMAGE "SF-IMAGE" 0 SF-OPTION "SF-OPTION" '("Option 1" "Option 2" "Option 3") SF-PATTERN "SF-PATTERN" "Wood" SF-STRING "SF-STRING" "Test String" SF-TOGGLE "SF-TOGGLE" TRUE SF-VALUE "SF-VALUE" "0" SF-FILENAME "SF-FILENAME" "/")
Результатом скрипта будет следующий диалог:
Ладно, вернемся к делу, давайте закончим наш скрипт. Мы должны решить, какие типы аргументов использовать? Если мы хотим создать шрифт, то первым делом нам нужен текст. Поэтому мы используем SF-STRING, потом нам нужно будет выбрать шрифт (используем SF-FONT) и добавим SF-VALUE, для ввода размера шрифта.
Создание блока script-fu-register я предоставлю Вам. Если Вы сейчас не хотите себя в этом пробовать, можете посмотреть в законченном скрипте ниже.
Сейчас, когда у нас есть готвый блок script-fu-register, пора бы уже добавить в файл и какой-нибудь код. Для начала вставим в файл наши две вспомогательные функции: my-duplicate-layer и my-layer-add-border. Дальше методом copy/paste (скопировал/вставил) соберем наши эксперементы в консоли Скрипт-Фу вместе. И перенесем вызов функции gimp-display-new в конец нашей главной функции, в этом случае мы не будем наблюдать как создается наше изображение. Также мы добавим еще одну вспомагательную функцию, которая обрежет готовое изображение до правильного размера. Законченный скрипт должен выглядеть примерно так: (прим. перев.: некоторые ф-ии в версии gimp-2.2 обозначены как deprecated, поэтому выкладываю оригинал и работающий скрипт под версию gimp 2.2)
;GIMP 1.0.x (define (my-image-to-layer-size image layer) (gimp-layer-set-offsets layer 0 0) (gimp-image-resize image (car (gimp-drawable-width layer)) (car (gimp-drawable-height layer)) 0 0)) (define (my-layer-add-border layer border) (let* ((width (car (gimp-drawable-width layer))) (height (car (gimp-drawable-height layer)))) (gimp-layer-resize layer (+ width border) (+ height border) (/ border 2) (/ border 2)))) (define (my-duplicate-layer image layer) (let* ((dup-layer (car (gimp-layer-copy layer 1)))) (gimp-image-add-layer image dup-layer 0) dup-layer)) (define (my-make-metal-font text font font-size) (let* ((image (car (gimp-image-new 256 256 RGB))) (bottom-font-layer (car (gimp-text-fontname image -1 0 0 text 0 TRUE font-size PIXELS font)))) (let* ((top-font-layer (my-duplicate-layer image bottom-font-layer))) (my-layer-add-border bottom-font-layer 20) (gimp-layer-set-preserve-trans bottom-font-layer 0) (gimp-gradients-set-active "Four_bars") (gimp-selection-layer-alpha bottom-font-layer) (gimp-selection-grow image 3) (gimp-blend bottom-font-layer CUSTOM NORMAL LINEAR 100 0 REPEAT-NONE FALSE 0 0 0 0 200 50) (gimp-selection-layer-alpha top-font-layer) (gimp-blend top-font-layer CUSTOM NORMAL LINEAR 100 0 REPEAT-NONE FALSE 0 0 0 50 200 0) (gimp-selection-clear image) (let* ((new-layer (car (gimp-image-merge-visible-layers image EXPAND-AS-NECESSARY)))) (my-image-to-layer-size image new-layer)) (gimp-display-new image)) )) (script-fu-register "my-make-metal-font" "<Toolbox>/Xtns/Script-Fu/Logos/Metal Font..." "Create an example image of a custom gradient" "Federico Mena Quintero" "Federico Mena Quintero" "June 1997" "" SF-STRING "Text" "The GIMP" SF-FONT "Font" "-*-blippo-*-r-*-*-24-*-*-*-p-*-*-*" SF-VALUE "Font Size" "50" )
;GIMP-2.2 (define (my-image-to-layer-size image layer) (gimp-layer-set-offsets layer 0 0) (gimp-image-resize image (car (gimp-drawable-width layer)) (car (gimp-drawable-height layer)) 0 0)) (define (my-layer-add-border layer border) (let* ((width (car (gimp-drawable-width layer))) (height (car (gimp-drawable-height layer)))) (gimp-layer-resize layer (+ width border) (+ height border) (/ border 2) (/ border 2)))) (define (my-duplicate-layer image layer) (let* ((dup-layer (car (gimp-layer-copy layer 1)))) (gimp-image-add-layer image dup-layer 0) dup-layer)) (define (my-make-metal-font text font font-size) (let* ((image (car (gimp-image-new 256 256 RGB))) (bottom-font-layer (car (gimp-text-fontname image -1 0 0 text 0 TRUE font-size PIXELS font)))) (let* ((top-font-layer (my-duplicate-layer image bottom-font-layer))) (my-layer-add-border bottom-font-layer 20) (gimp-layer-set-preserve-trans bottom-font-layer 0) (gimp-context-set-gradient "Four bars") (gimp-selection-layer-alpha bottom-font-layer) (gimp-selection-grow image 3) (gimp-edit-blend bottom-font-layer CUSTOM NORMAL LINEAR 100 0 REPEAT-NONE FALSE FALSE 0 0 0 0 0 200 50) (gimp-selection-layer-alpha top-font-layer) (gimp-edit-blend top-font-layer CUSTOM NORMAL LINEAR 100 0 REPEAT-NONE FALSE FALSE 0 0 0 0 50 200 0) (gimp-selection-clear image) (let* ((new-layer (car (gimp-image-merge-visible-layers image EXPAND-AS-NECESSARY)))) (my-image-to-layer-size image new-layer)) (gimp-display-new image)) )) (script-fu-register "my-make-metal-font" "<Toolbox>/Xtns/Script-Fu/Logos/Metal Font..." "Create an example image of a custom gradient" "Federico Mena Quintero" "Federico Mena Quintero" "June 1997" "" SF-STRING "Text" "The GIMP" SF-FONT "Font" "-*-blippo-*-r-*-*-24-*-*-*-p-*-*-*" SF-VALUE "Font Size" "50" )
Далее следует список самых распространенных ошибок в Скрипт-Фу.
Возвращаемые значения
Когда функция возвращает значение, оно всегда инкапсулировано в списке; и даже не важно, возвращается одно значение или несколько. В том случае, если возвращаемое значение должно быть списком, как, например, возвращаемое значение функции gimp-color-picker, то оно инкапсулировано в так называемом особенном списке (extra list).
Если возвращаются несколько значений, они тоже будут в списке, первое возвращаемое значение - первый элемент списка, второе - второй и т.д. Итак, не забывайте использовать вызов функции car, для получения правильного значения.
R5SR - это документ, описывающий язык схем, но к сожалению язык, используемый в GIMP не соотвествует R5SR. Это потому, что GIMP использует в качестве интерпретатора SIOD. SIOD - это небольшая реализация языка схем, ценная только потому, что предоставляет подмножество функций R5SR; имена некоторых функций были изменены. Например, не имеется функции display, есть только функция print. Краткий список функций языка схем, поддерживающихся в GIMP, Вы можете посмотреть на сайте SIOD. Еще хуже всего то, что GIMP поддерживает не все функции предоставленные на сайте SIOD, но это является хорошей стартовой точкой. Вы также можете использовать функцию apropos для поиска нужной функции.
=> (apropos "write") (fwrite writes swrite write-mask stroke-overwrite)
Когда Вы только начинаете знакомиться с Скрипт-Фу, или когда Вы уже достигли определенных результатов в этом, Вы очень часто попадаете в ситуацию, когда Ваш скрипт не работает. Делает ситуацию хуже еще и то, что иногда Вы не получаете никаких сообщений об ошибке. В большинстве случаев ошибка элементарная, но ее поиск занимает много времени. Следующие советы должны облегчить Вам поиск ошибок.
Прежде всего проверьте, что Ваш скрипт синтаксически корректен, это значит, что все открытые скобки и кавычки - закрыты. Редактор с автоматической подсветкой синтаксиса поможет Вам в этом.
Второе - Вы могли забыть добавить функцию car для одного из возвращаемых значений. Для проверки таких ошибок, методом copy/paste выполните каждую строчку скрипта в консоли Скрипт-Фу.
ERROR: Invalid types specified for arguments<code> Это наиболее частая ошибка, которую Вы будете получать. Если скрипт не выполнился по другой ошибке, значит баг не в этом. Когда Вы вызываете функцию с двумя или более аргументами, и получаете следующую ошибку: <code scheme>=> (gimp-image-get-layers) ERROR: too few arguments (see errobj)
То нужно просто посмотреть переменную errorbj: в ней хранится список ожидаемых аргументов и реально переданных.
=> (print errobj) ((image)) ()
И последнее: если Ваша функция до сих пор не работает, попробуйте поставить вызовы print в нужные места. Это хороший способ проверить работоспособность функции. Чтобы видеть вывод функции print, скрипт должен быть запущен с консоли Скрипт-Фу.
До этого момента я описывал, что Вы можете сделать в Скрипт-Фу, но также существует множество вещей, которые нельзя реализовать в Скрипт-Фу.
Первая вещь, которую Вы захотите реализовать - это передача “умных” значение по умолчанию в качестве аргументов Вашим функциям. Плохо то, что Вы не сможете сделать этого; Вы можете передавать только константные значния при геристрации скрипта в Скрипт-Фу. Допустим Вы хотите, чтобы значение по умолчанию какой-либо переменной было половиной ширины изображения. Ничего не получится. Вам придется жить с постоянным значением.
Другая вещь, которую Вы можете захотеть сделать - это встроить некую часть GUI в Ваш скрипт. И опять у Вас ничего не выйдет. Переменные SF-* это весь GUI в Вашем скрипте. Например, для окошка предпросмотра уже нужно писать не скрипт, а GIMP плагин.
Придет время и возможно Вы захотите написать свой собственный фильтр и эффект, требующий управления изображением на уровне пикселей. Эту вещь впринципе можно сделать и в Скрипт-Фу, но это будет очень медленно. И опять решением будет являться написание GIMP плагина.
Также Вы можете захотеть, например, просмотреть все файлы определенного каталога и открыть все изображения. Но и это невозможно. На сайте SIOD описана функция opendir, но когда Вы попытаетесь ее применить в скрипте она не заработает, как и многие другие функции SIOD.
=> (opendir "/") ERROR: unbound variable (errobj opendir)
Для решения проблемы с каталогом, Вы можете поработать над реализацией такого метода: хранить имена файлов каталога в файле и читать из него. Еще лучший вариант - это использовать скрипты Perl-Fu, Python-Fu и плагины GIMP.
Хорошая идея посмотреть чужие скрипты в процессе обучения. Скрипты Скрипт-Фу, например, можно найти в каталоге, где установлен GIMP - /usr/share/gimp/1.1/scripts/. Также на страничке gimp.org есть ссылки на сайты, посвященные Скрипт-Фу. А еще Вы можете загрузить мои скрипты, их Вы можете найти здесь, но будте осторожны: большинство из них не документировано, и некоторые не везде работают.