Как писать скрипты для Gimp 2.x? Осваиваем Scheme (Script-Fu). Часть 2.

от
Работа с графикой    gimp, script-fu

Итак, в первой части мы освоились в Scheme той версии, которая стоит в Gimp 2.x. Сейчас же рассмотрим механизмы взаимодействия с функционалом данного графического редактора.

Запускаем скрипт из файла
Скажите, как удобней записывать код – так?

  1. (define (dlina-p m n) (+ (* m 2) (* n 2)))

Или так?

  1. (define
  2.  
  3.     (dlina-p m n)
  4. (
  5.  
  6. + (* m 2) (* n 2)
  7. ))

Думаю, второй вариант лучше.

К тому же, писать более сложные скрипты в одну строчку просто не получится. Поэтому в Gimp 2.x скрипты, сделанные как отдельные функции, можно загружать из текстовых файлов. Как это сделать?

Для ваших скриптов Gimp создает отдельную директорию в пользовательской папке (для Windows 7):

C:\Users\(ИМЯ ПОЛЬЗОВАТЕЛЯ)\.gimp-2.8\scripts

Или

C:\Users\(ИМЯ ПОЛЬЗОВАТЕЛЯ)\.gimp-2.6\scripts

У меня это, например «C:\Users\M_N\.gimp-2.8\scripts». В этой папке создаем обычный текстовый файл (с разрешением .txt то есть) и переименовываем разрешение в «.scm».

Открываем файл любым текстовым редактором – например, Notepad++. Записываем туда функцию «dlina-p», код которой я написал выше. Сохраняем.

Если у вас открыт Gimp, заходим в «скрипты => Script-Fu => Обновить сценарии». Ждем несколько секунд – готово! Наша функция добавилась в базу данных.

  refresh-scripts.jpg
 
Иначе просто откройте Gimp, и скрипт добавится при загрузке.

Далее заходим в консоль, и набираем такой код:

  1. (dlina-p 10 4)

В ответ получите число 28. Функция загружена!

Добавляем скрипт в меню Gimp’а
Для этого есть функции script-fu-register и script-fu-menu-register.

Создайте в директории со скриптами текстовый файл, переименуйте разрешение в .scm, а название сделайте – например, simple-window.

Откройте текстовый редактор и напишите этот код:

  1. (script-fu-register
  2.  
  3. " simple-window"
  4. "Простое окно"
  5. "Мое первое простое окно"
  6. "M_N"
  7. "bY M_N"
  8. "2016 год до н.э."
  9. "RGB*, GRAY*, INDEXED*"
  10.  
  11. SF-IMAGE "my_image" 0
  12. SF-DRAWABLE "my_layer" 0
  13.  
  14. SF-ADJUSTMENT "Крутилка" '(10 1 30 1 4 1 0)
  15. )

Итак, что мы сделали? Скажу сразу – не заморачивайтесь пока с параметрами SF-IMAGE, SF-DRAWABLE и SF-ADJUSTMENT. Их подробно разберем в следующей части.

Нам важны самые первые параметры. Разберем их:

1 – название скрипта. Имя, которое мы дали файлу со скриптом. В нашем случае это «simple-window».
2 – имя скрипта. Так он будет подписан в меню. В нашем случае мы его увидим под именем «Простое окно».
3 – описание скрипта.
4 – имя автора.
5 – копирайт.
6 – дата выпуска.
7 – типы поддерживаемых цветовых моделей. В нашем случае:

RGB либо RGBA (с добавлением альфа-канала, т.е. прозрачности);
GRAY либо GRAYA – картинка просто в оттенках серого, или с добавлением альфа-канала;
INDEXED либо INDEXEDA – это цветовая модель с индексированными цветами. Т.е. если ее не перевести в RGB, рисовать на ней можно только имеющимися на картинке цветами.

Все понятно? Тогда ниже пишем следующий код:

  1. (script-fu-menu-register
  2.  
  3. "simple-window"
  4. "<Image>/Filters/Мои скрипты"
  5. )

1-й аргумент содержит имя скрипта, аналогично таковому из вышеописанной функции.

2-й аргумент содержит путь, по которому скрипт прописывается в меню. В данном случае он будет тут:

  way-to-script.jpg
 
А можно его вынести в самое главное меню Gimp’а, прописав путь так: "<Image>/Мои скрипты".

  main-menu.jpg
 
Или вообще запихнуть в кучу подразделов: "<Image>/Filters/Простые скрипты/Мои скрипты/Простые окна/Примеры".

many-menu.jpg
 
Сохраняем файл, обновляем скрипты, ищем наше «Простое окно» в меню Gimp’а. Запускаем.

Открывается окно с крутилкой:
 
  simple-window.jpg

Ура! Мы научились регистрировать скрипт в меню и создавать бесполезное окно.

Работаем с окном. Элементы окна.
Сейчас мы разберем, что значат SF-ADJUSTMENT и прочие SF-IMAGE. Создаем еще один файл .scm – на этот раз назовем его, например, test-window.

Запишем в него такой код:

  1. (script-fu-register
  2.  
  3. " test-window"
  4. "Тестовое окно"
  5. "Примеры элементов окна"
  6. "M_N"
  7. "bY M_N"
  8. "2016 год до н.э."
  9. "RGB*, GRAY*, INDEXED*"
  10.  
  11. SF-IMAGE "image" 0
  12. SF-DRAWABLE "layer" 0
  13.  
  14. SF-ADJUSTMENT "Крутилка" '(10 1 30 1 4 0 0)
  15. SF-COLOR "Цвет" '(50 100 250)
  16. SF-VALUE "Значение" "Что-то написано"
  17. SF-PALETTE "Выбери палитру" "Volcano"
  18. SF-STRING "Тут написан текст" "Текст"
  19. SF-FONT "Шрифт" "Calibri"
  20. SF-OPTION "Выбирай" '("Один" "Два" "Три")
  21. SF-TOGGLE "Поставь галку" FALSE
  22. SF-GRADIENT "Градиент" ""
  23. SF-PATTERN "Текстурка" ""
  24. SF-BRUSH "Кисть" '("Bristles 02" 100 44 0)
  25. SF-ENUM "Интерполяция" '("InterpolationType" "linear")
  26. SF-DIRNAME "Папковыбиралка" ""
  27. SF-FILENAME "Файловыбиралка" (string-append "" gimp-data-directory "/scripts/images/beavis.jpg")
  28.  
  29. )
  30.  
  31. (script-fu-menu-register
  32.  
  33. " test-window"
  34. "<Image>/Filters/Мои скрипты"
  35. )

Как видите, почти simple-window. Только добавилась толпа аргументов, начинающихся на SF-. Если вы запустите этот скрипт, у вас появится такое окно:

  window-elements.jpg
 
Это – все элементы, которые можно засунуть в окно скрипта. По крайней мере, все, что нашел в официальной документации к Gimp 2.x.

Каждый элемент опишу так подробно, как сумел разобраться.

SF-IMAGE.

Во втором параметре содержится ссылка на ID открытого изображения. Первый параметр можно оставить пустым. Если скрипт создает изображение с нуля, можно его не писать.
 
SF-DRAWABLE.

Второй параметр содержит ссылку на ID активного слоя в открытом изображении. Первый параметр можно оставить пустым. Если скрипт создает изображение с нуля, можно его не писать.

SF-ADJUSTMENT.

Тут мы выбираем произвольное значение в промежутке между заданными нами минимальным и максимальным числом. Первый аргумент – название, я его назвал «крутилка».

Второй – список. Вот, что значит каждый его элемент слева направо:

1. На каком значении будет стоять крутилка (слайдер) по умолчанию.
2. Минимальное значение.
3. Максимальное значение.
4. Шаг изменения значения при перемещении крутилки или нажатии стрелок вниз-вверх.
5. Шаг изменения значения при нажатиях кнопок Page Up и Page Down.
6. Если 0, дробные числа использовать не можем. Если 1 – можем.
7. Если 1, крутилка исчезает – остается только текстовое поле с выбираемым нами значением. Если 0, она появляется.

SF-COLOR.

Выбираем цвет в системе RGB. Первый аргумент – имя. Второй содержит список. В нем все просто:

1-й элемент. Красный цвет по умолчанию (от 0 до 255).
2-й элемент. Зеленый цвет по умолчанию (от 0 до 255).
3-й элемент. Синий цвет по умолчанию (от 0 до 255).

SF-VALUE.

Текстовое поле. Первый аргумент содержит имя поля. Второй – текст по умолчанию.

Как я понял, лучше использовать SF-STRING, т.к. тут проблема с кавычками. Их нужно экранировать вручную.

SF-STRING.

То же, что SF-VALUE.

SF-PALETTE.

Выбор цветовой палитры. Первый аргумент содержит название, а второй имя палитры.

SF-FONT.

Выбираем шрифт текста. Первое значение – имя элемента, второе содержит имя шрифта.

SF-OPTION.

Селектор – в списке строки со значениями, среди которых нужно выбирать.

SF-TOGGLE.

Можно ставить галочку. Второй аргумент содержит либо FALSE, либо TRUE.

SF-GRADIENT.

Выбор градиента. Второе значение содержит имя градиента по умолчанию, его можно оставить пустым.

SF-PATTERN.

Выбор текстуры. Второе значение содержит имя текстуры по умолчанию – его тоже можно оставить пустым.

SF-BRUSH.

Выбор кисти. 2-й элемент содержит список – разберем его элементы по порядку:

1. Строка с именем кисти по умолчанию.
2. Значение прозрачности от 0 до 100, причем 100 – непрозрачность.
3. Значение интервала.
4. Режим кисти.

SF-ENUM.

Интерполяция. 2-й аргумент содержит список с типом интерполяции во 2-м элементе.

SF-DIRNAME.

Выбор директории или диска по умолчанию.

SF-FILENAME.

Выбор файла. Второй аргумент – полный путь к файлу.

Пишем первый скрипт
Например, сделаем новую картинку с текстом на нужном нам фоне. Делаем новый scm-файл с именем script-fu-text-image и пишем в него код:

  1. (define (script-fu-text-image text color)
  2.  
  3.    (let*
  4.      (
  5.  
  6.        (logo (car (gimp-image-new 400 200 RGB)))
  7.        (back (car (gimp-layer-new
  8.  
  9.             logo
  10.             400
  11.             200
  12.             0
  13.             "background-color"
  14.             100
  15.             0
  16.  
  17.        )))
  18.  
  19.        (text_layer (car (gimp-text-fontname
  20.  
  21.             logo
  22.             -1
  23.             20
  24.             69
  25.             text
  26.             -1
  27.             FALSE
  28.             40
  29.             1
  30.             "Calibri"
  31.  
  32.        )))
  33.      )
  34.  
  35.      (gimp-image-undo-disable logo)
  36.  
  37.      (gimp-image-add-layer logo back 0)
  38.      (gimp-palette-set-background color)
  39.      (gimp-edit-clear back)
  40.      (gimp-image-raise-layer-to-top logo text_layer)
  41.  
  42.      (gimp-display-new logo)
  43.  
  44.      (gimp-image-undo-enable logo)
  45.    )
  46. )  
  47.  
  48. (script-fu-register
  49.  
  50. "script-fu-text-image"  
  51. "Текст в картинке"
  52. "Текст в картинке"
  53. "M_N"
  54. "bY M_N"
  55. "2016 год до н.э."
  56. "RGB"
  57.  
  58.  SF-STRING "Пиши чего-нибудь"   "Текст давай"
  59.  SF-COLOR "Цвет фона" '(0 250 0)
  60. )
  61.  
  62. (script-fu-menu-register
  63.  
  64. "script-fu-text-image"
  65. "<Image>/Filters/Мои скрипты"
  66. )

Сохраняем, обновляем скрипты. Готово?

Как видите – пока мало понятного. Тогда разберем работу скрипта подробно.

1. Возвращаем параметры с окна
Да, скрипт начинает свою работу именно с функции script-fu-register, а не с первой строчки. Сразу после запуска открывается окно, о механизмах работы которого сказано выше.

Поскольку мы делаем картинку с чистого листа, параметры SF-IMAGE и SF-DRAWABLE нам не нужны.

Нам нужно лишь указать текст в SF-STRING и цвет фона в SF-COLOR. А теперь – ВНИМАНИЕ!

Как данные с окна передаются в нашу функцию?
Смотрим на самую первую строчку кода:

  1. (define (script-fu-text-image text color)

Мы объявляем пользовательскую функцию с аргументами «text» и «color». Как вы поняли – текст и цвет фона.

После того, как вы нажмете кнопку ОК, параметры из script-fu-register автоматически записываются в аргументы созданной и зарегистрированной нами функции script-fu-text-image в таком порядке:

• Если первым стоит SF-STRING, записываем данные с него в первый аргумент пользовательской функции – text.
• Если вторым стоит SF-COLOR, записываем с него данные во второй аргумент – color.

И т.д. Треттий параметр записывается в треттий аргумент, четвертый – в четвертый…

2. Объявляем все переменные, создаем изображение и нужные слои
2.1 Создаем новое изображение

Это делает функция gimp-image-new. Смотрим на строчку с ее применением:

  1. (logo (car (gimp-image-new 400 200 RGB)))

Обратите внимание на car – очевидно, функция возвращает результат в виде списка. Так вот, запомните:

Любая функция GIMP’а возвращает результат в виде списка.

Поэтому его приходится доставать с помощью car.

Итак, какие входные параметры имеет функция gimp-image-new? Как видим:

1. Длина холста (изображения).
2. Ширина холста.
3. Цветовая модель.

У нас создается пустое изображение разрешением 400 на 200 точек с цветовой моделью RGB.

Возвращает же функция ID созданной картинки, который достаем из списка и записываем в переменную «logo». Кстати, обратите внимание на пару строчек выше:

  
  1. (let*
  2.     (

Мы оперируем локальными переменными, весь код функции находится внутри «let*»:

  1. (let*
  2.     (
  3. ;объявляем переменные и записываем в них параметры
  4.     )
  5.  
  6. ;код
  7. )

2.2 Создаем слой для фона
Для этого есть код:

  1. (back (car (gimp-layer-new
  2.  
  3.             logo
  4.             400
  5.             200
  6.             0
  7.             «background-color»
  8.             100
  9.             0
  10.  
  11.        )))

Функция gimp-layer-new отвечает за создание нового слоя. В нее входят такие параметры:

1. ID изображения, в котором создаем слой. У нас ID записан в переменной logo.
2. Длина слоя в пикселях.
3. Ширина слоя в пикселях.
4. Цветовая модель, с которой работает слой. В нашем случае цифра 0 означает, что мы используем RGB. А вот – все возможные:

RGB-IMAGE (0), RGBA-IMAGE (1), GRAY-IMAGE (2), GRAYA-IMAGE (3), INDEXED-IMAGE (4), INDEXEDA-IMAGE (5).

5. Имя слоя в виде строки.
6. Прозрачность от 0 до 100. Если 100 – слой непрозрачный.
7. Режим сочетания слоев. В данной случае стоит NORMAL-MODE (цифра 0). Все возможные режимы:

NORMAL-MODE (0), DISSOLVE-MODE (1), BEHIND-MODE (2), MULTIPLY-MODE (3), SCREEN-MODE (4), OVERLAY-MODE (5), DIFFERENCE-MODE (6), ADDITION-MODE (7), SUBTRACT-MODE (8), DARKEN-ONLY-MODE (9), LIGHTEN-ONLY-MODE (10), HUE-MODE (11), SATURATION-MODE (12), COLOR-MODE (13), VALUE-MODE (14), DIVIDE-MODE (15), DODGE-MODE (16), BURN-MODE (17), HARDLIGHT-MODE (18), SOFTLIGHT-MODE (19), GRAIN-EXTRACT-MODE (20), GRAIN-MERGE-MODE (21), COLOR-ERASE-MODE (22), ERASE-MODE (23), REPLACE-MODE (24), ANTI-ERASE-MODE (25).

После того, как слой создан, мы сохраняем его ID в переменной back.

2.3 Добавляем слой с текстом
Это происходит вот так:

  1. (text_layer (car (gimp-text-fontname
  2.  
  3.             logo
  4.             -1
  5.             20
  6.             69
  7.             text
  8.             -1
  9.             FALSE
  10.             40
  11.             1
  12.             "Calibri"
  13.  
  14.        )))

Функция gimp-text-fontname может либо вставить текст на существующий слой, либо на новый. Вот ее входные параметры:

1. ID изображения, с которым работаем.
2. ID слоя, куда добавляем текст. Если стоит -1:

• Создаем новый слой.
• Добавляем туда текст.
• Возвращаем ID созданного слоя с текстом.

3. X-координата слоя.
4. Y-координата слоя.
5. Текст. В нашем случае он записан в переменную «text».
6. Окантовка текст. Если -1 – без окантовки.
7. Сглаживание. Если FALSE – без сглаживания.
8. Размер шрифта.
9. Единица измерения размера шрифта. Если 1, в пунктах. Если 0 – в пикселях.
10. Имя шрифта.

Поскольку мы создали для текста новый слой, записываем его в переменную «text_layer».

Итак – все слои созданы, все переменные объявлены! Переходим к исполняемой части программы.

3. Разбираем исполняемый код
3.1 Запрет-разрешение на запись истории операций

Обратите внимание на функции gimp-image-undo-disable и gimp-image-undo-enable. В них как-бы заключен весь код.

Они включают и отключают запрет на ведение записи операций в историю. Без этих функций вполне можно обойтись, но тогда после исполнения скрипта с помощью кнопок «Отменить» и «Вернуть» вы сможете просматривать все операции, которые он проделал с изображением.

Кстати, очень удобно при отладке.

В нашем случае мы сначала запрещаем запись истории (функция gimp-image-undo-disable), затем снова разрешаем (функция gimp-image-undo-enable). Единственный параметр, который они требуют – ID изображения, с которым работаем.

3.2 Рисуем фон
Для начала необходимо добавить на холст слой с фоном. Это делает функция gimp-image-add-layer:

  1. (gimp-image-add-layer logo back 0)

Она требует:

1. ID изображения.
2. ID слоя.
3. Позицию слоя.

Далее окрашиваем фон в нужный нам цвет:

  1. (gimp-palette-set-background color)

Функция gimp-palette-set-background требует только один параметр – цвет в системе RGB. Он автоматически записался в переменную «color» после того, как в нашем окне мы нажали кнопку ОК.

Последний шаг – очищаем слой с фоном. Иначе он будет черный, а не такой, как нам нужно.

  1. (gimp-edit-clear back)

Делается это с помощью функции gimp-edit-clear, которой необходимо сообщить ID слоя.

Фон готов!

3.3 Помещаем текст
Дело в том, что функция «gimp-text-fontname» уже добавила слой на наше изображение. Но сейчас он оказался под фоном, поскольку добавился перед ним.

Теперь нужно его поднять наверх. Делает это функция gimp-image-raise-layer-to-top:

  1. (gimp-image-raise-layer-to-top logo text_layer)

Требует она ID изображение и ID слоя, с которым работаем.

3.4 Создаем окно и помещаем в него получившуюся картинку
Делается это с помощью gimp-display-new:

  1. (gimp-display-new logo)

Функция требует ID изображения, которое нужно поместить в новое окно.

Все! Скрипт написан.

  text-in-window.jpg
 
Вот – результат его работы:

  text-in-window-result.jpg
 
А что, если нам надо работать с открытым изображением?

Добавим текст на открытую картинку!
Тут все проще:

  1. (define (script-fu-text-image-to img drw text)
  2.  
  3.    (let*
  4.      (
  5.        (logo (car (gimp-image-duplicate img)))
  6.  
  7.        (text_layer (car (gimp-text-fontname
  8.  
  9.             logo
  10.             -1
  11.             20
  12.             69
  13.             text
  14.             -1
  15.             FALSE
  16.             40
  17.             1
  18.             "Calibri"
  19.  
  20.        )))
  21.      )
  22.  
  23.     (gimp-display-new logo)
  24.    )
  25. )  
  26.  
  27. (script-fu-register
  28.  
  29. "script-fu-text-image-to"  
  30. "Текст в открытой картинке"
  31. "Текст в картинке"
  32. "M_N"
  33. "bY M_N"
  34. "2016 год до н.э."
  35. "RGB* INDEXED*"
  36.  
  37.   SF-IMAGE       "IMG" 0
  38.   SF-DRAWABLE    "DRW" 0
  39.  
  40.  SF-STRING "Пиши чего-нибудь"   "Текст давай"
  41. )
  42.  
  43. (script-fu-menu-register
  44.  
  45. "script-fu-text-image-to"
  46. "<Image>/Filters/Мои скрипты"
  47. )

Что у нас изменилось?

1. Добавились параметры SF-IMAGE и SF-DRAWABLE, поскольку мы работаем с открытым изображением.
2. Вместо функции создания изображения появилась gimp-image-duplicate. Она создает копию открытой картинки возвращает ее ID.
3. Поскольку в создании фона нет нужды, отсутствует весь код отвечающий за него.
4. Слой с текстом добавляется после создания дубликата изображения, поэтому ложится поверх него. И нужды поднимать его наверх – нет.
5. Весь остальной код сводится к созданию нового окна с получившимся изображением. Поэтому нужды разрешать-запрещать запись истории изменений нет.

Готово! Обзор основ написания скриптов на Sceme для Gimp 2.x завершен.
Теперь, понимая основные принципы, можно писать любые скрипты. Главное – знать, как применять ту или иную функцию. Посмотреть список их всех можно, нажав кнопку «Посмотреть...» в консоли:

  console-view.jpg

Там же есть все описания к ним.

  gimp-function.jpg

Два раза щелкнув по нужной функции она скопируется в поле ввода консоли с нужными ей аргументами.

  gimp-function-inp.jpg

Если возникнут какие-то заминки, пишите в комментарии.
  • +7
  • views 9067