Наш первый Hello World в GIMP!

Наша цель нарисовать приветствие на изображении в GIMP. Но для того что бы вывести что то на изображение, это изображение у нас должно быть. Мы можем создать его в ручную. Просто средствами GIMP, или же создать его прямо из плагина Script-fu.

Научим плагин создавать изображения, определив функцию создания изображений. Что надо знать, так это то что изображение состоит из слоев - layer, в нашем новом изображении будет изначально только один слой. Изображение будет создано и заполнено ТЕКУЩИМ цветом фона, установленного в Гимп, но мы могли бы вполне себе и задать цвет фона создаваемого изображения.

(define (create-1-layer-img w h)
   (let* ((i1  (car (gimp-image-new w h RGB)))
         (l1  (car (gimp-layer-new i1 w h
                                RGB "layer 1" 100 LAYER-MODE-NORMAL-LEGACY))))
      (gimp-image-undo-disable i1)
      (gimp-image-add-layer i1 l1 0)
      ;;(gimp-palette-set-background '(0 127 50))
      (gimp-edit-fill l1 FILL-BACKGROUND)
      (gimp-display-new i1)
      (gimp-image-undo-enable  i1)
      i1))

Да забыл сказать, этот код подходит для версии 2.10. А GIMP хотя и медленно, но постоянно меняется, и я работал в двух версиях, так что можете сравнить

код для версии 2.6:
(define (create-1-layer-img w h)
   (let* ((i1  (car (gimp-image-new w h RGB)))
         (l1  (car (gimp-layer-new i1 w h
                                RGB "layer 1" 100 NORMAL))))
      (gimp-image-undo-disable i1)
      (gimp-image-add-layer i1 l1 0)
      ;;(gimp-palette-set-background '(0 127 50))
      (gimp-edit-fill l1 BG-IMAGE-FILL)
      (gimp-display-new i1)
      (gimp-image-undo-enable  i1)
      i1))

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

Используем эту функцию и создадим изображение:

(define img (create-1-layer-img 640 480))
;;можно получить img или ошибку:
;;Error: eval: unbound variable: LAYER-MODE-NORMAL-LEGACY
;;если применить код для версии 2.10 в gimp версии 2.6

В переменной img будет храниться handle(хендл), что можно перевести как ручка, нечто за что можно держаться и управлять этим объектом, представляющий собой некий числовой идентификатор, передавая который обратно в гимп с помощью функций гимп, мы можем работать с внутренним объектом гимпа. Типы этих объектов могут быть совершенно разными: изображение, слой или какой либо другой тип.

Так же мы можем создать изображение с помощью средств гимпа или даже загрузить его из файла. Но для того чтобы работать с ним нам надо знать хендл этого изображения. Получить список всех изображений можно с помощью функции:

(gimp-image-list)
;;(1 #(1))

(define img 1)
;;img

и просто присвоить известный числовой идентификатор переменной img и так же работать с ним как с хендлом.

Далее нам надо определится с тем каким шрифтом выводить текст, список всех известных гимпу шрифтов, можно получить с помощью функции:

;;посмотреть список фонтов присутствующих в системе
(gimp-fonts-get-list ".*")
;;очень длинный вывод
(gimp-fonts-get-list "Sans")
;;у меня список из 218 элементов в Линукс и 23 в Видовс.

функция ищет по шаблону имени фонта и выдает все фонты имена которых соответствуют шаблону, регулярному выражению. Из этого списка мы можем выбрать фонт, которым будем рисовать наш текст.

(gimp-text-layer-new img "Привет Мир!" "DejaVu Sans" 1 1)
;;(3)

Введя эту команду в консоль скрипт-фу, мы к сожалению не увидим добавленного текста, но она вернет опять таки некий хендл(как список), созданного текстового слоя. Используя его можно получить некоторую информацию о созданном текстовом слое. К сожалению, до тех пор пока слой не будет добавлен в изображение, все функции работы с текстовым слоем выдают ошибку. Поэтому слой с текстом будем добавлять с помощью функции:

(define (insert-text1 i str font size unit)
  (let ((l (car (gimp-text-layer-new i str font size unit))))
    (gimp-image-add-layer i l 0)
	l))
	
(insert-text1 img "Привет Мир!" "DejaVu Sans" 1 1)
;;4

Не смотря на единички, а вернее благодаря последней единице(обозначающей вывод текста в неких юнитах), в линукс текст получился гигантским, в виндовс - вполне нормальным. Но мы попробуем второй заход. И да, если изображение "подпорчено", неудачной функцией в ГИМПе можно легко откатиться на предыдущую версию изображения воспользовавшись "Историей действий", это такой список изображений, выбрав то изображение которое вы считаете нормальным, у нас это пока единственное пустое изображение, выберем его.

(insert-text1 img "Привет Мир!" "DejaVu Sans" 100 0)
;;6

Последний 0 в вызове функции обозначает, размер будет указан в пикселах, а 100 обозначает условную высоту текста. Полученный слой приблизительно соответствует этой величине.

"Привет Мир!"
"Привет Мир!"

Из текстового слоя можно получить не мало интересной информации, помните хендл полученный нами для данного слоя 6, и именно его мы используем в указанных ниже функциях, если у вас хендл другой используйте его:

(gimp-text-layer-get-text 6)
;;("Привет Мир!")
(gimp-text-layer-get-language 6)
;;("ru_RU")
(gimp-text-layer-get-font-size 6)
;;(100.0 0)
(gimp-text-layer-get-font 6)
;;("DejaVu Sans")
(gimp-text-layer-get-base-direction 6)
;;(0)
(gimp-drawable-height 6)
(gimp-drawable-width  6)
;;(117)(668)

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

Но что не менее важно, можно эту информацию и установить, т.е изменить сам текстовый слой.

(gimp-text-layer-set-color 6 '(255 255 0))
(#t)
(gimp-text-layer-set-font 6  "URW Gothic Oblique")
(gimp-text-layer-set-font 6   "Terminus")
(#t)
(gimp-text-layer-set-text 6   "Хай, Бро!\nКак живёшь?")
(#t)
(gimp-text-layer-set-base-direction 6  4);;в 2.6 направления 4 нет, есть 0 или 1.
(#t)

И вот результат:

"Докатились!"
"Докатились!"

Таким образом видно, Гимп предлагает очень богатый набор функций по выводу текста на изображение. И что не менее важно, слой создаваемый функцией gimp-text-layer-new является не просто картой пикселей, но объектом, динамически изменяющим свой вид, в зависимости от устанавливаемых для него параметров.

Как запомнить результаты нашей работы? Надо объединить слои в один и дать ГИМПу команду сохранения:

(gimp-image-flatten img)
;;(7)
(gimp-file-save 1 img (car (gimp-image-active-drawable img))
                "D:\\WORK\\gimp\\test-hello1.png" "test-hello1.png" ) 
;;(#t)

Путь указан для Виндовса, для Линкуса всё тоже самое, но с обычным слешем, конечно же без диска. И да, почему я всё время CARкаю? Потому что многие процедуры, типа gimp-image-active-drawable возвращают список, хотя казалось бы, почему список? активный слой может быть только один, но она возвращает список, а мы берём из него 1 элемент. Поэтому CAR.

И на этом пока всё.

Комментарии (7)


  1. DrewUnknown
    01.11.2024 11:49

    по мне статья ни о чем, т.к не ясно, а зачем там этот скриптовый язык


    1. Nikita_64
      01.11.2024 11:49

      Согласен: было бы понятнее, если бы привели примеры, где это можно использовать. Например, манипуляции с сотней фотографий: изменить размер, перевести в ч/б, добавить водяной знак или надпись (например, дату из EXIF). Или создание сложных геометрических рисунков, рисование графиков функций и пр.

      Есть ли средства анализа изображения?


    1. BigBeaver
      01.11.2024 11:49

      Алгоритмическое рисование. Фильтры. Автоматизация типовых операций.


  1. isumix
    01.11.2024 11:49

    О, не зназ что тут тоже Lisp, нравится.


  1. checkpoint
    01.11.2024 11:49

    А куда вводить этот код ? У GIMP-а есть какая-то консоль ?


    1. IisNuINu Автор
      01.11.2024 11:49

      Я конечно дико извиняюсь, но это серия уроков по Script-fu GIMP и на первом уроке я рассказал где находиться консоль Script-fu в GIMP https://habr.com/ru/articles/854918/ . Так что да, там есть консоль.


      1. checkpoint
        01.11.2024 11:49

        Извиняюсь, этот первый урок почему-то прошел мимо. Изучим.