Графический редактор GIMP предоставляет широкие возможности для создания расширений на языках программирования Scheme (функциональный язык, сходный с LISP) или Python. Для доступа к системным операциям и регистрации собственных действий используется общий реестр Procedural Database (PDB), через который можно выполнять любые действия со встроенными механизмами GIMP (например, создание изображения). В этой статье мы рассмотрим основы создания расширений на Python 3 и возможные подходы к тестированию расширений через PDB.
По умолчанию для создания расширений используется Scheme
и компонент Script-Fu
, который предоставляет методы для регистрации расширений. Список существующих процедур можно посмотреть в меню Help -> Procedure Browser, среди которых есть процедуры для выполнения действий внутри GIMP
(например, с префиксом file
для загрузки-выгрузке файлов, gimp
для обработки изображений), для регистрации дополнительных пунктов меню (gimp-plugin-menu-register
), регистрации генераторов миниатюр (gimp-register-thumbnail-loader
) и др. Процедуры могут принимать значения (например, название дополнительного пункта меню) и, в некоторых случаях, названия процедур-обработчиков события (например, нажатия на пункт меню). Также процедуры могут возвращать значения (например, gimp-version
возвращает версию GIMP). При описании процедуры указывается название, описание, метаданные об авторских правах, перечисление аргументов и результатов функции с уточнением типа данных.
Для использования python с целью создания расширений для GIMP необходимо установить модуль python-fu. GIMP версии 2.99 (и последующий GIMP3) будут поддерживать Python3 и мы будем использовать их в своей статье:
sudo apt update
sudo apt install flatpak
flatpak install --user https://flathub.org/beta-repo/appstream/org.gimp.GIMP.flatpakref
flatpak run org.gimp.GIMP//beta
Для более ранних версий GIMP поддержка существовала только для Python 2, но начиная для бета-версии уже доступен Python 3. После запуска GIMP перейдем в Filters -> Development -> Python Fu -> Python Console.
Для доступа к API GIMP будем использовать символ Gimp:
>>> Gimp.version()
'2.99.14'
Доступ ко встроенным действиям возможен через реестр Pdb:
>>> Gimp.get_pdb()
<Gimp.PDB object at 0x7fcf20523d40 (GimpPDB at 0x557496007ca0)>
Описание интерфейса может быть найдено на этой странице. Для доступа к процедуре можно использовать методы lookup_procedure
(возвращает доступ к объекту процедуры для исследования и вызова, а также привязке пункта меню):
Gimp.get_pdb().lookup_procedure('gimp-plug-in-menu-branch-register')
или run_procedure
:
>>> Gimp.get_pdb().run_procedure('gimp-version').index(0)
<enum GIMP_PDB_SUCCESS of type Gimp.PDBStatusType>
>>> Gimp.get_pdb().run_procedure('gimp-version').index(1)
'2.99.14'
Также можно передавать значения, например для выбора цвета переднего плана:
>>> Gimp.get_pdb().run_procedure('gimp-context-set-foreground', [Gimp.RGB(255,0,0)])
Для создания плагина будем расширять класс Gimp.Plugin
и переопределять методы do_create_procedure
и do_query_procedures
, также дополнительно проверим корректность версии Gimp
:
import gi
gi.require_version('Gimp', '3.0')
from gi.repository import Gimp
gi.require_version('GimpUi', '3.0')
from gi.repository import GimpUi
from gi.repository import Gio
class SamplePlugin(Gimp.PlugIn):
def do_query_procedures(self):
# получить список процедур
self.set_translation_domain("gimp30-python",
Gio.file_new_for_path(Gimp.locale_directory()))
return [ 'python-fu-sample-plugin' ]
def do_create_procedure(self, name):
procedure = Gimp.Procedure.new(self, name,
Gimp.PDBProcType.PLUGIN,
self.sample_procedure, None, None)
procedure.set_menu_label("Sample Plugin")
procedure.set_attribution("Dmitrii Zolotov",
"Dmitrii Zolotov",
"2023")
procedure.add_menu_path("<Image>/Filters/SamplePlugin")
return procedure
def sample_procedure(self, procedure, args, data):
return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, "OK")
Gimp.main(SamplePlugin.__gtype__, sys.argv)
Для тестирования плагина после установки мы можем использовать обнаружение PDB для проверки сигнатуры или результата выполнения функции:
a = Gimp.get_pdb().lookup_procedure('python-fu-sample_plugin')
r = a.run([])
assert r.index(0)==Gimp.PDBStatusType.SUCCESS
assert r.index(1)=='OK'
В расширениях могут создаваться разных типы процедур:
Gimp.Procedure - базовый класс, определяет абстрактное действие с указанными аргументами (может возвращать результат);
Gimp.FileProcedure- процедура для модификации возможностей по работе с файлами;
Gimp.LoadProcedure - процедура для обработки изображения при загрузке (например, для поддержки других форматов файлов);
Gimp.SaveProcedure - обработка изображения при сохранении файла (для экспорта в другие форматы);
Gimp.ImageProcedure - обработка изображения (например, этот тип используется при создании фильтров);
Gimp.BatchProcedure - пакетная обработка;
Gimp.ThumbnailProcedure - подготовка миниатюры.
Для выполнения преобразований можно использовать возможности GEGL, либо подключать другие библиотеки для работы с изображениями (PIL, OpenCV и др.). Для тестирования преобразований изображения (например, фильтров) можно использовать сравнение снимков изображения по степени сходства на основе нескольких преобразований нескольких тестовых изображений (для проверки можно передавать название исходного изображения и путь для сохранения результата как аргументы процедуры), например так:
import cv2
import numpy as np
img1 = cv2.imread('source.jpg')
img2 = cv2.imread('target.jpg')
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
def mse(img1, img2):
h, w = img1.shape
diff = cv2.subtract(img1, img2)
err = np.sum(diff**2)
mse = err/(float(h*w))
return mse, diff
error, diff = mse(img1, img2)
assert mse<5
Также для использования в Python доступны все методы, опубликованные в классе Gimp для получения текущего контекста запущенного редактора и выбранных инструментов, операции с файлами, просмотра списка открытых изображений (list_images). Для манипуляции изображением возможно использовать методы Gimp.Image (в частности, через него можно выполнять изменение размера изображения, управление слоями, выделение и операции с фрагментами) и многое другое.
Пример плагин для GIMP 3 (2.99.14) можно посмотреть в этом проекте.
В завершение хочу пригласить вас на бесплатный урок, где мы познакомимся с системой автоматизации развёртывания и управления приложениями Docker, посмотрим как использовать некоторые базовые команды Docker CLI и попробуем "упаковать" тесты в Docker-контейнер.
U235a
В коде вычисления mse ошибка. cv2.subtract делает вычитание с насыщением: 42-255=0. Нужно использовать cv2.absdiff. Или сразу cv2.PSNR для похожих целей.