Как писать скрипты для Gimp 2.x? Осваиваем Scheme (Script-Fu). Часть 1.
от M_N
В этой статье я покажу основы создания скриптов на Scheme (Script-Fu) для Gimp 2.x. Мы разберем:
1. Основы программирования на Scheme для Gimp 2.6 - 2.8.
2. Загрузку скриптов из файлов.
3. Добавление скрипта в меню Gimp’а.
4. Окна и его элементы.
5. Передачу параметров с окна в скрипт.
6. Написание простейшего скрипта, создающего изображение с тектом и фоном.
Статью разобью на 2 части. В 1-й пройдемся по Scheme, во второй разберем взаимодействие с функциями Gimp'а.
Кто не знает, что такое и чем полезны скрипты в графических редакторах – прочтите спойлер:
Теперь – к делу!
Сначала откроем консоль. В Gimp 2.6 и Gimp 2.8 это делается одинаково:
• Запустите Gimp 2.x
• Выберите «фильтры»
• Наведите курсор на «Script-Fu» в самом низу списка
• В появившемся меню выберите «Консоль»
• Ждем 10-15 секунд, и наша консоль открыта!
Запустим «Привет, мир» – внизу для этого есть текстовое поле.
Наберите "Привет, мир!" (обязательно в кавычках) и нажмите «Enter». Вот что получится:
Работает? Отлично! Едем дальше…
Знакомимся со Scheme
Язык прост до безобразия. Однако – все выражения заключаются в скобки. Скобок получается столько, что путаешься на раз-два.
Чтобы избежать говололомки, установите текстовый редактор с подсветкой кода и скобок. Например, Notepad++.
Но об этом позже. Постигать основы языка на маленьких примерах удобнее прямо в консоли. Делать это будем так.
Я даю примеры кода и объясняю, как он работает. Вы его перепечатываете в консоль (не копировать => вставить, именно перепечатываете!) и запускаете. Так материал усвоится эффективнее.
Все манипуляции с кодом в консоли Gimp запоминает. Если мы набрали в одной строчке код, объявляющий переменную, она останется в памяти. Второй строчкой в эту переменную можно что-то записать, а третьей прочитать.
Чтобы Gimp забыл все действия, закройте консоль и запустите ее снова.
Все примеры рабочие – проверял их лично.
1. Переменные
1.1 Глобальные переменные
Работа с ними выглядит проще всего. Например – вводим в консоль сначала одну строку, потом другую:
Что мы сделали? Оператор define создает переменную (или функцию, до них дойдем чуть ниже). В первой строке мы объявили переменную «x».
Оператор set! задает значение переменной. Второй строкой в переменную «x» мы записали значение «8».
Проверяем – вводим в консоль имя нашей переменной:
На выходе видим:
1.2 Локальные переменные
Пишем такой пример:
Тут начинается путаница со скобками. Разберем по частям:
1. Оператор let* объявляет локальные переменные. Они действуют внутри скобок, в которые заключен весь наш пример.
2. ((a 4)) – да, именно двойные скобки. Чтобы было понятней, почему, определим сразу две переменные: ((a 4) (b 8)). Как видим, каждая определяется в своих скобках – сначала имя, потом значение. А участок кода, где определяются все переменные, заключен в свои скобки.
3. Имя переменной «a» в конце выражения выводит ее значение в консоль.
Запустим тот же код, но с двумя переменными:
Поочередно выводим значения «a» и «b» в консоль и убеждаемся, что все работает.
1.3 Переменные и строки
Строка заключается в кавычки – "строка". Она легко присваивается переменной:
Проверяем:
Видим в консоли:
Работает!
1.4 Списки
Список – это массив. Определяется он таким образом:
или
В первом варианте все значения в скобочках, записанные через пробел – элементы списка. Во втором первое значение является оператором объявления списка, а все остальные его элементы. На мой взгляд, удобней пользоваться первым вариантом.
Список может быть пустым:
Список может содержать как числа, так и строки:
Список можно присвоить переменной:
Проверяем:
В консоли видим: (1 2 3 4 "пять").
1.5 Вложенные списки
Список может состоять из списков, или включать в себя списки (аналог многомерных массивов). Например:
Мы создали список из 3-х списков – '(1 2), '(3 4), '(5 6). Или так:
Теперь он содержит 2 вложенных списка '(1 2), '(3 4) и 2 числа – 5, 6.
Чуть ниже мы узнаем о том, как работать со списками.
2. Вычисления
Работа с вычислениями в Scheme отличается от того, как это происходит во многих языках программирования. Выполните в консоли такой код:
Что сейчас вообще произошло? Вот что:
1. Оператор (вернее, функция) * выполняет умножение. Он пишется в начале выражения.
2. Далее пишутся данные, с которыми работает оператор. В данном случае – 2 числа, 8 и 8.
То есть, если вы напишите (8 * 8) – увидите ошибку, ибо интерпретатор примет первое значение в выражении, число 8, за оператора.
Дальше – веселее:
Сейчас мы пытаемся посчитать вот это:
Сначала считаются выражения с умножением. Потом получившиеся результаты делятся. На выходе получается число 1.
2.1 Вычисления и переменные
С глобальными переменными все просто:
Тогда как с локальными – один момент:
Выражения с использованием этих переменных нужно писать после блока их определения. Сколько угодно. Например:
(В консоль выведется только результат последнего выражения)
За пределами скобок оператора let* локальные переменные не существуют, следственно и работа с ними там невозможна.
3. Функции
Как я говорил выше, команда define также создает функции:
1. Первый блок в скобках после define – (double-func a), задает ее имя (первое значение) и входные данные (остальные значения).
2. Второй блок после define – (+ a a), выражения с исполняемым кодом функции. В данном случае мы удваиваем значение входной переменной «a».
Проверим работу функции:
На выходе получим значение «20».
Теперь напишем что-нибудь сложнее:
Эта функция вычисляет длину сторон прямоугольника. Вот как это работает:
1. Сначала нам надо узнать длину «m» и ширину «n» прямоугольника – (dlina-p m n).
2. Затем удвоить их – (* m 2), (* n 2).
3. И потом сложить получившиеся значения – (+ (* m 2) (* n 2)).
Проверяем:
На выходе получится число «28».
Примечание
Обратите внимание – не называйте свою функцию именем уже существующей. Если вы это сделаете, пользоваться ей не сможете.
Например, есть предопределенная функция sin. Она вычисляет синус (спасибо, кэп!). Проверим:
Получаем число «-0,7568024953.0». А теперь делаем так:
Проверяем еще раз, не закрывая консоли:
Что видим? На выходе число «16»! А все потому, что теперь функция под именем «sin» вычисляет квадрат числа – (* x x).
Также можно связать имя существующей функции с именем переменной:
Теперь, если мы напишем так:
это будет равносильно выражению:
3.1 Функции для работы со строками
Строки можно объединять:
Тут функция string-append объединяет несколько строк "Это", " - ", "строка" в одну.
Теперь, не закрывая консоль, выполняем сразу следующее выражение:
Функция string-length считает количество символов в строке. У нас результат ее работы будет «12» – переменная mystr содержит строку "Это - строка", длина которой 12 символов.
3.2 Функции работы со списками
В списки можно добавлять новые элементы ( в т.ч. и другие списки):
Функция cons добавляет перед первым элементом списка любое значение. В нашем случае – цифру 0. Первый аргумент функции тот самый элемент списка, который добавляем. Второй и есть наш список, куда добавляем.
В итоге он будет выглядеть так – (0 1 2 3 4 5).
Списки можно объединять:
Что мы сейчас сделали?
1. Создали списки '(0 1 2) и '(3 4 5) в переменных lista и listb.
2. Объединили эти два списка функцией append и записали получившееся в переменную lista. На выходе получаем список (0 1 2 3 4 5).
Из списка можно извлечь первый элемент:
Функция car извлекает из списка первый элемент (или, как еще говорят, голову). Который мы записываем в переменную listx, где ранее содержался наш список.
Теперь listx содержит значение «1».
Из списка можно удалить первый элемент:
Все точно так же, только теперь функция cdr возвращает список без первого элемента (хвост списка) – (2 3 4 5). Который мы записываем в переменную listx.
Это все, что можно делать со списками.
А что, если мы имеем такое: (1 2 '("три" "четыре") 5)? И нам надо добраться до первого значения вложенного списка '("три" "четыре").
Алгоритм выглядит так:
1. Идем до вложенного списка, поочередно удаляя первые элементы.
2. Когда первым элементом становится он, извлекаем его функцией car.
3. Извлекаем первое значение вложенного списка функцией car.
Воплощаем в жизнь:
Обратите внимание на порядок исполнения кода! Он читается не слева направо, а из младшей скобки в старшую. Сначала срабатывают функции cdr, потом car. Результат – значение "три" в переменной listx.
Впрочем, можно написать проще:
Теперь посмотрите на функцию caaddr. Она выполняет то же, что и нагромождение car и cdr. Две буквы a обозначают две функции car, а две буквы d обозначают две функции cdr.
Можно использовать функцию cadr, caadr, caddr… Все они выполняют последовательность car-cdr соответственно количеству букв a и d в названии.
4. Логические операции.
4.1 Условия.
Запустите в консоли такое выражение:
Функция if проверяет истинность выражения в скобках. Если оно верно, выполняется первое условие. Иначе – второе, хотя его можно не использовать. В таком случае, если выражение ложно, ничего выполняться не будет.
Результат работы нашего кода будет «правда».
Теперь исполните это:
Выражение ложно – результат работы «неправда». Можно также использовать функции =, >=, <=.
Теперь пример сложнее.
Он более практичен, т.к. все данные у нас в переменных, и в условии работаем мы тоже с ними.
В x и y записываем два числа, которые сравниваем в условии.
Если условие верно, записываем в переменную say «правда». Иначе – «неправда».
И еще лучше…
4.2 Рекурсия в одну строку
Запустите в консоли это:
Это – рекурсия, когда функция вызывает саму себя. Продолжается бесконечное число раз, если в коде не предусмотрим процесс выхода из нее.
Как работает рекурсия в нашем примере?
1. Оператор define создает функцию rec_in с одним входящим значением n.
2. Условие проверяет истинность выражения n > 0.
3. Если истина – вызываем функцию rec_in. Как видите, в самой же rec_in.
4. Во второй строке мы вызываем нашу функцию, задавая ей число 10. При последующих вызовах rec_in в ней самой мы посылаем ей это значение, каждый раз уменьшаемое на единицу – ( - n 1).
5. В конце концов, оно станет равно нулю и условие n > 0 станет ложным.
6. Выполнится второе выражение – функция просто вернет значение переменной n и закончит свою работу. То есть «0».
4.3 Цикл while
1. Определяем переменные m и n.
2. Устанавливаем значения n = 10, m = 0.
3. Цикл будет продолжаться, пока n > 0.
4. Первое выражение - присваиваем переменной m ее же значение, сложенное с n.
5. Второе выражение - присваиваем переменной n ее же значение, уменьшенное на единицу.
6. Смотрим значение переменной m. Оно должно быть 55.
Как видите, мы посчитали сумму всех чисел в промежутке от 1 до 10 (10+9+8+7… +1).
Итог: В этой части мы изучили основы Scheme. По крайней мере, его модификации, присутствующей в Gimp 2.x. Как видите, ничего сложного нет.
Кстати – если кому-то пригодится, генератор случайных чисел тут выглядит вот так: (rand 255). Где 255 – любое число, в промежутке от 0 до которого нужно генерировать случайные числа.
Вот пример использования:
***
В следующей части я расскажу о загрузке функций из файлов, регистрации в меню, работе с окнами и создании первого скрипта, взаимодействующего с функционалом Gimp.
Следующая статья →1. Основы программирования на Scheme для Gimp 2.6 - 2.8.
2. Загрузку скриптов из файлов.
3. Добавление скрипта в меню Gimp’а.
4. Окна и его элементы.
5. Передачу параметров с окна в скрипт.
6. Написание простейшего скрипта, создающего изображение с тектом и фоном.
Статью разобью на 2 части. В 1-й пройдемся по Scheme, во второй разберем взаимодействие с функциями Gimp'а.
Кто не знает, что такое и чем полезны скрипты в графических редакторах – прочтите спойлер:
Открыть спойлер
Теперь – к делу!
Сначала откроем консоль. В Gimp 2.6 и Gimp 2.8 это делается одинаково:
• Запустите Gimp 2.x
• Выберите «фильтры»
• Наведите курсор на «Script-Fu» в самом низу списка
• В появившемся меню выберите «Консоль»
• Ждем 10-15 секунд, и наша консоль открыта!
Запустим «Привет, мир» – внизу для этого есть текстовое поле.
Наберите "Привет, мир!" (обязательно в кавычках) и нажмите «Enter». Вот что получится:
Работает? Отлично! Едем дальше…
Знакомимся со Scheme
Язык прост до безобразия. Однако – все выражения заключаются в скобки. Скобок получается столько, что путаешься на раз-два.
Чтобы избежать говололомки, установите текстовый редактор с подсветкой кода и скобок. Например, Notepad++.
Но об этом позже. Постигать основы языка на маленьких примерах удобнее прямо в консоли. Делать это будем так.
Я даю примеры кода и объясняю, как он работает. Вы его перепечатываете в консоль (не копировать => вставить, именно перепечатываете!) и запускаете. Так материал усвоится эффективнее.
Все манипуляции с кодом в консоли Gimp запоминает. Если мы набрали в одной строчке код, объявляющий переменную, она останется в памяти. Второй строчкой в эту переменную можно что-то записать, а третьей прочитать.
Чтобы Gimp забыл все действия, закройте консоль и запустите ее снова.
Все примеры рабочие – проверял их лично.
1. Переменные
1.1 Глобальные переменные
Работа с ними выглядит проще всего. Например – вводим в консоль сначала одну строку, потом другую:
- (define x)
- (set! x 8)
Что мы сделали? Оператор define создает переменную (или функцию, до них дойдем чуть ниже). В первой строке мы объявили переменную «x».
Оператор set! задает значение переменной. Второй строкой в переменную «x» мы записали значение «8».
Проверяем – вводим в консоль имя нашей переменной:
- x
На выходе видим:
1.2 Локальные переменные
Пишем такой пример:
- (let* ((a 4)) a)
Тут начинается путаница со скобками. Разберем по частям:
1. Оператор let* объявляет локальные переменные. Они действуют внутри скобок, в которые заключен весь наш пример.
2. ((a 4)) – да, именно двойные скобки. Чтобы было понятней, почему, определим сразу две переменные: ((a 4) (b 8)). Как видим, каждая определяется в своих скобках – сначала имя, потом значение. А участок кода, где определяются все переменные, заключен в свои скобки.
3. Имя переменной «a» в конце выражения выводит ее значение в консоль.
Запустим тот же код, но с двумя переменными:
- (let* ((a 4) (b 8)) a)
- (let* ((a 4) (b 8)) b)
Поочередно выводим значения «a» и «b» в консоль и убеждаемся, что все работает.
1.3 Переменные и строки
Строка заключается в кавычки – "строка". Она легко присваивается переменной:
- (define x)
- (set! x "строка")
Проверяем:
- x
Видим в консоли:
Работает!
1.4 Списки
Список – это массив. Определяется он таким образом:
- '(1 2 3 4)
или
- (list 1 2 3 4)
В первом варианте все значения в скобочках, записанные через пробел – элементы списка. Во втором первое значение является оператором объявления списка, а все остальные его элементы. На мой взгляд, удобней пользоваться первым вариантом.
Список может быть пустым:
- '()
Список может содержать как числа, так и строки:
- '(1 2 3 4 "пять")
Список можно присвоить переменной:
- (define mylist)
- (set! mylist '(1 2 3 4 "пять"))
Проверяем:
- mylist
В консоли видим: (1 2 3 4 "пять").
1.5 Вложенные списки
Список может состоять из списков, или включать в себя списки (аналог многомерных массивов). Например:
- '( '(1 2) '(3 4) '(5 6))
Мы создали список из 3-х списков – '(1 2), '(3 4), '(5 6). Или так:
- '('(1 2) '(3 4) 5 6)
Теперь он содержит 2 вложенных списка '(1 2), '(3 4) и 2 числа – 5, 6.
Чуть ниже мы узнаем о том, как работать со списками.
2. Вычисления
Работа с вычислениями в Scheme отличается от того, как это происходит во многих языках программирования. Выполните в консоли такой код:
- (* 8 8)
Что сейчас вообще произошло? Вот что:
1. Оператор (вернее, функция) * выполняет умножение. Он пишется в начале выражения.
2. Далее пишутся данные, с которыми работает оператор. В данном случае – 2 числа, 8 и 8.
То есть, если вы напишите (8 * 8) – увидите ошибку, ибо интерпретатор примет первое значение в выражении, число 8, за оператора.
Дальше – веселее:
- (/ (* 8 8) (* 8 8))
Сейчас мы пытаемся посчитать вот это:
Сначала считаются выражения с умножением. Потом получившиеся результаты делятся. На выходе получается число 1.
2.1 Вычисления и переменные
С глобальными переменными все просто:
- (define x)
- (define y)
- (set! x 8)
- (set! y 8)
- (+ x y)
Тогда как с локальными – один момент:
- (let* ((a 8) (b 2)) (- a b))
Выражения с использованием этих переменных нужно писать после блока их определения. Сколько угодно. Например:
- (let* ((a 8) (b 2)) (- a b) (+ a b))
(В консоль выведется только результат последнего выражения)
За пределами скобок оператора let* локальные переменные не существуют, следственно и работа с ними там невозможна.
3. Функции
Как я говорил выше, команда define также создает функции:
- (define (double-func a) (+ a a))
1. Первый блок в скобках после define – (double-func a), задает ее имя (первое значение) и входные данные (остальные значения).
2. Второй блок после define – (+ a a), выражения с исполняемым кодом функции. В данном случае мы удваиваем значение входной переменной «a».
Проверим работу функции:
- (double-func 10)
На выходе получим значение «20».
Теперь напишем что-нибудь сложнее:
- (define (dlina-p m n) (+ (* m 2) (* n 2)))
Эта функция вычисляет длину сторон прямоугольника. Вот как это работает:
1. Сначала нам надо узнать длину «m» и ширину «n» прямоугольника – (dlina-p m n).
2. Затем удвоить их – (* m 2), (* n 2).
3. И потом сложить получившиеся значения – (+ (* m 2) (* n 2)).
Проверяем:
- (dlina-p 10 4)
На выходе получится число «28».
Примечание
Обратите внимание – не называйте свою функцию именем уже существующей. Если вы это сделаете, пользоваться ей не сможете.
Например, есть предопределенная функция sin. Она вычисляет синус (спасибо, кэп!). Проверим:
- (sin 4)
Получаем число «-0,7568024953.0». А теперь делаем так:
- (define (sin x) (* x x))
Проверяем еще раз, не закрывая консоли:
- (sin 4)
Что видим? На выходе число «16»! А все потому, что теперь функция под именем «sin» вычисляет квадрат числа – (* x x).
Также можно связать имя существующей функции с именем переменной:
- (define my-func)
- (set! my-func sin)
Теперь, если мы напишем так:
- (my-func 4)
это будет равносильно выражению:
- (sin 4)
3.1 Функции для работы со строками
Строки можно объединять:
- (define mystr)
- (set! mystr (string-append "Это" " - " "строка"))
Тут функция string-append объединяет несколько строк "Это", " - ", "строка" в одну.
Теперь, не закрывая консоль, выполняем сразу следующее выражение:
- (string-length mystr)
Функция string-length считает количество символов в строке. У нас результат ее работы будет «12» – переменная mystr содержит строку "Это - строка", длина которой 12 символов.
3.2 Функции работы со списками
В списки можно добавлять новые элементы ( в т.ч. и другие списки):
- (define listx)
- (set! listx '(1 2 3 4 5))
- (cons 0 listx)
Функция cons добавляет перед первым элементом списка любое значение. В нашем случае – цифру 0. Первый аргумент функции тот самый элемент списка, который добавляем. Второй и есть наш список, куда добавляем.
В итоге он будет выглядеть так – (0 1 2 3 4 5).
Списки можно объединять:
- (define lista)
- (define listb)
- (set! lista '(0 1 2))
- (set! listb '(3 4 5))
- (set! lista (append lista listb))
Что мы сейчас сделали?
1. Создали списки '(0 1 2) и '(3 4 5) в переменных lista и listb.
2. Объединили эти два списка функцией append и записали получившееся в переменную lista. На выходе получаем список (0 1 2 3 4 5).
Из списка можно извлечь первый элемент:
- (define listx)
- (set! listx '(1 2 3 4 5))
- (set! listx (car listx))
Функция car извлекает из списка первый элемент (или, как еще говорят, голову). Который мы записываем в переменную listx, где ранее содержался наш список.
Теперь listx содержит значение «1».
Из списка можно удалить первый элемент:
- (define listx)
- (set! listx '(1 2 3 4 5))
- (set! listx (cdr listx))
Все точно так же, только теперь функция cdr возвращает список без первого элемента (хвост списка) – (2 3 4 5). Который мы записываем в переменную listx.
Это все, что можно делать со списками.
А что, если мы имеем такое: (1 2 '("три" "четыре") 5)? И нам надо добраться до первого значения вложенного списка '("три" "четыре").
Алгоритм выглядит так:
1. Идем до вложенного списка, поочередно удаляя первые элементы.
2. Когда первым элементом становится он, извлекаем его функцией car.
3. Извлекаем первое значение вложенного списка функцией car.
Воплощаем в жизнь:
- (define listx)
- (set! listx '(1 2 ("три" "четыре") 5))
- (set! listx (car (car (cdr ( cdr listx)))))
Обратите внимание на порядок исполнения кода! Он читается не слева направо, а из младшей скобки в старшую. Сначала срабатывают функции cdr, потом car. Результат – значение "три" в переменной listx.
Впрочем, можно написать проще:
- (define listx)
- (set! listx '(1 2 '("три" "четыре") 5))
- (set! listx (caaddr listx))
Теперь посмотрите на функцию caaddr. Она выполняет то же, что и нагромождение car и cdr. Две буквы a обозначают две функции car, а две буквы d обозначают две функции cdr.
Можно использовать функцию cadr, caadr, caddr… Все они выполняют последовательность car-cdr соответственно количеству букв a и d в названии.
4. Логические операции.
4.1 Условия.
Запустите в консоли такое выражение:
- (if ( > 3 0 ) "правда" "неправда")
Функция if проверяет истинность выражения в скобках. Если оно верно, выполняется первое условие. Иначе – второе, хотя его можно не использовать. В таком случае, если выражение ложно, ничего выполняться не будет.
Результат работы нашего кода будет «правда».
Теперь исполните это:
- (if ( < 3 0 ) "правда" "неправда")
Выражение ложно – результат работы «неправда». Можно также использовать функции =, >=, <=.
Теперь пример сложнее.
- (define x)
- (define y)
- (define say)
- (set! x 12)
- (set! y 11)
- (if (= x y) (set! say "правда") (set! say "неправда"))
Он более практичен, т.к. все данные у нас в переменных, и в условии работаем мы тоже с ними.
В x и y записываем два числа, которые сравниваем в условии.
Если условие верно, записываем в переменную say «правда». Иначе – «неправда».
И еще лучше…
4.2 Рекурсия в одну строку
Запустите в консоли это:
- (define (rec_in n) (if (> n 0) (rec_in( - n 1)) n ))
- (rec_in 10)
Это – рекурсия, когда функция вызывает саму себя. Продолжается бесконечное число раз, если в коде не предусмотрим процесс выхода из нее.
Как работает рекурсия в нашем примере?
1. Оператор define создает функцию rec_in с одним входящим значением n.
2. Условие проверяет истинность выражения n > 0.
3. Если истина – вызываем функцию rec_in. Как видите, в самой же rec_in.
4. Во второй строке мы вызываем нашу функцию, задавая ей число 10. При последующих вызовах rec_in в ней самой мы посылаем ей это значение, каждый раз уменьшаемое на единицу – ( - n 1).
5. В конце концов, оно станет равно нулю и условие n > 0 станет ложным.
6. Выполнится второе выражение – функция просто вернет значение переменной n и закончит свою работу. То есть «0».
4.3 Цикл while
- (define n)
- (define m)
- (set! n 10)
- (set! m 0)
- (while (> n 0) (set! m (+ m n)) (set! n (- n 1)) )
- m
1. Определяем переменные m и n.
2. Устанавливаем значения n = 10, m = 0.
3. Цикл будет продолжаться, пока n > 0.
4. Первое выражение - присваиваем переменной m ее же значение, сложенное с n.
5. Второе выражение - присваиваем переменной n ее же значение, уменьшенное на единицу.
6. Смотрим значение переменной m. Оно должно быть 55.
Как видите, мы посчитали сумму всех чисел в промежутке от 1 до 10 (10+9+8+7… +1).
Итог: В этой части мы изучили основы Scheme. По крайней мере, его модификации, присутствующей в Gimp 2.x. Как видите, ничего сложного нет.
Кстати – если кому-то пригодится, генератор случайных чисел тут выглядит вот так: (rand 255). Где 255 – любое число, в промежутке от 0 до которого нужно генерировать случайные числа.
Вот пример использования:
- (define r)
- (set! r (rand 255))
***
В следующей части я расскажу о загрузке функций из файлов, регистрации в меню, работе с окнами и создании первого скрипта, взаимодействующего с функционалом Gimp.
Как писать скрипты для Gimp 2.x? Осваиваем Scheme (Script-Fu). Часть 2.