Definição🔗

Um plugin do GIMP é um módulo carregado dinamicamente pelo aplicativo que expõe um ou mais procedimentos via PDB. Plugins podem ser escritos em Python 3 (estilo moderno, com Gimp.PlugIn) ou em C (acesso direto a libgimp, máxima performance). O plugin aparece no GIMP como item de menu (ou como procedimento chamável via script) e roda no mesmo processo, comunicando-se com o core via GObject Introspection.

Use o desenvolvimento de plugins (em vez de scripts .scm/.py) quando: precisa distribuir como módulo instalável; quer total controle sobre UI, configuração e ciclo de vida; ou precisa de performance máxima (caso C).

Conceitos🔗

flowchart TB
    subgraph Plugin Python
    A1[shebang + encoding] --> A2[import gi]
    A2 --> A3[class GimpPlugin Gimp.PlugIn]
    A3 --> A4[do_query_procedures]
    A3 --> A5[do_create_procedure]
    A3 --> A6[do_set_i18n]
    A3 --> A7[run]
    A3 --> A8[Gimp.main]
    end
    subgraph Plugin C
    B1[#include libgimp/gimp.h] --> B2[PLUG_IN_INFO]
    B2 --> B3[query]
    B2 --> B4[run]
    B3 --> B5[gimp_install_procedure]
    end
    A8 --> PDB[PDB]
    B5 --> PDB
    PDB --> Core[libgimp core]

Conceitos-chave:

  • Gimp.PlugIn — classe base Python que o GIMP instancia para descobrir o que o plugin expõe. O fluxo e: do_query_procedures retorna nomes; para cada nome, do_create_procedure constrói a definição; quando o usuário aciona o menu, o GIMP chama run.
  • Gimp.ImageProcedure — tipo de procedimento mais comum. Recebe image, drawables, config, run_data no método run.
  • Diretório próprio — o plugin deve ficar em uma pasta com o mesmo nome do executável/arquivo: plug-ins/meu_plugin/meu_plugin.py ou meu_plugin (binário).
  • Permissão de execução — em Linux/macOS, o arquivo Python ou binário C precisa de chmod +x.
  • PDBProcType — classifica o procedimento: PLUGIN (binário externo), EXTENSION (permanentemente carregado), INTERNAL (built-in).

Fluxo de Uso🔗

sequenceDiagram
    participant U as Usuário
    participant G as GIMP
    participant P as Plugin
    participant PDB
    U->>G: Iniciar GIMP
    G->>P: Carregar (do_query_procedures)
    P-->>G: ["meu-plugin"]
    G->>P: do_create_procedure("meu-plugin")
    P-->>G: Definição (menu, tipos, args)
    G->>PDB: Registra procedimento
    U->>G: Menu > Meu Plugin
    G->>P: run(procedure, image, drawables, ...)
    P->>PDB: Chamadas (gimp_image_new, etc.)
    PDB-->>P: Resultados
    P-->>G: procedure.new_return_values(SUCCESS)

Exemplos Práticos🔗

Exemplo 1 — Plugin Python 3 mínimo (Hello World)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import gi
gi.require_version('Gimp', '3.0')
from gi.repository import Gimp, GLib

class HelloPlugin(Gimp.PlugIn):
    def do_query_procedures(self):
        return ["hello-py3"]

    def do_set_i18n(self, name):
        return False

    def do_create_procedure(self, name):
        procedure = Gimp.ImageProcedure.new(self, name,
                                            Gimp.PDBProcType.PLUGIN,
                                            self.run, None)
        procedure.set_image_types("*")
        procedure.set_menu_label("Hello Python 3")
        procedure.add_menu_path('<Image>/Filters/Hello/')
        procedure.set_documentation("Hello world plugin",
                                    "Exibe uma mensagem no console",
                                    name)
        procedure.set_attribution("Autor", "Autor", "2024")
        return procedure

    def run(self, procedure, run_mode, image, drawables, config, run_data):
        Gimp.message("Ola do GIMP 3!")
        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())

Gimp.main(HelloPlugin.__gtype__, sys.argv)

Salve como ~/.config/GIMP/2.10/plug-ins/hello_py3/hello_py3.py, chmod +x, reinicie o GIMP. Item aparecerá em Filters > Hello > Hello Python 3.

Exemplo 2 — Plugin Python com parâmetros (GimpIntComboBox)

from gi.repository import Gimp, GLib, Gtk

class BorderPlugin(Gimp.PlugIn):
    def do_query_procedures(self):
        return ["border-add"]

    def do_set_i18n(self, name):
        return False

    def do_create_procedure(self, name):
        procedure = Gimp.ImageProcedure.new(self, name,
                                            Gimp.PDBProcType.PLUGIN,
                                            self.run, None)
        procedure.set_image_types("RGB*, GRAY*")
        procedure.set_menu_label("Adicionar Borda...")
        procedure.add_menu_path('<Image>/Filters/Border/')

        # Parametro: cor da borda
        procedure.add_color_argument("color", "Cor", "Cor da borda",
                                     True, (1.0, 1.0, 1.0), False)

        # Parametro: espessura em pixels
        procedure.add_int_argument("width", "Espessura",
                                   "Espessura da borda em pixels",
                                   1, 100, 5, False)
        return procedure

    def run(self, procedure, run_mode, image, drawables, config, run_data):
        cor = config.get_property("color")
        espessura = config.get_property("width")
        pdb.gimp_image_undo_group_start(image)
        for drw in drawables:
            pdb.gimp_image_select_rectangle(image, 0, 0, 0,
                                             pdb.gimp_image_width(image),
                                             pdb.gimp_image_height(image))
            pdb.gimp_selection_grow(image, espessura)
            pdb.gimp_context_set_foreground(cor)
            pdb.gimp_edit_fill(drw, FILL_FOREGROUND)
            pdb.gimp_selection_none(image)
        pdb.gimp_image_undo_group_end(image)
        Gimp.displays_flush()
        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())

Gimp.main(BorderPlugin.__gtype__, sys.argv)

add_color_argument e add_int_argument declaram parâmetros tipados que aparecem na GUI do GIMP. O objeto config no run expõe esses valores via get_property.

Exemplo 3 — Plugin C básico (libgimp 2.10)

#include <libgimp/gimp.h>

static void query(void);
static void run(const gchar *name,
                gint nparams,
                const GimpParam *param,
                gint *nreturn_vals,
                GimpParam **return_vals);

GimpPlugInInfo PLUG_IN_INFO = {
    NULL,    /* init */
    NULL,    /* quit */
    query,   /* query */
    run      /* run */
};

MAIN()

static void query(void) {
    static GimpParamDef args[] = {
        { GIMP_PDB_INT32,    "run-mode", "Run mode" },
        { GIMP_PDB_IMAGE,    "image",    "Input image" },
        { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" }
    };
    gimp_install_procedure(
        "plug-in-hello-c",
        "Hello C",
        "Exibe uma mensagem de teste",
        "Autor",
        "Copyright 2024",
        "2024",
        "<Image>/Filters/Hello C",
        "RGB*, GRAY*",
        GIMP_PDB_PLUGIN,
        G_N_ELEMENTS(args), 0,
        args, NULL);
}

static void run(const gchar *name,
                gint nparams,
                const GimpParam *param,
                gint *nreturn_vals,
                GimpParam **return_vals) {
    static GimpParam values[1];
    GimpPDBStatusType status = GIMP_PDB_SUCCESS;

    gimp_message("Ola do plugin C!\n");

    values[0].type = GIMP_PDB_STATUS;
    values[0].data.d_status = status;
    *nreturn_vals = 1;
    *return_vals = values;
}

Compilação:

gcc -o hello_c $(pkg-config --cflags libgimp-2.0) hello.c $(pkg-config --libs libgimp-2.0)
install -D -m 755 hello_c ~/.local/lib/gimp/2.0/plug-ins/hello_c/hello_c

Reinicie o GIMP. Item aparecerá em Filters > Hello C.

Exemplo 4 — Plugin Python que exporta PNG em lote

import os, glob
from gi.repository import Gimp, GLib

class ExportPlugin(Gimp.PlugIn):
    def do_query_procedures(self):
        return ["export-png-batch"]

    def do_set_i18n(self, name):
        return False

    def do_create_procedure(self, name):
        procedure = Gimp.ImageProcedure.new(self, name,
                                            Gimp.PDBProcType.PLUGIN,
                                            self.run, None)
        procedure.set_image_types("*")
        procedure.set_menu_label("Exportar PNG em lote")
        procedure.add_menu_path('<Image>/File/Export/')
        procedure.add_string_argument("pattern", "Padrao",
                                      "Glob para saida (ex: /tmp/out_*.png)",
                                      "/tmp/out_", False)
        return procedure

    def run(self, procedure, run_mode, image, drawables, config, run_data):
        pattern = config.get_property("pattern")
        drawable = image.get_active_drawable()
        existing = sorted(glob.glob(pattern))
        n = len(existing)
        saida = f"{pattern}{n:03d}.png"
        pdb.file_png_save(image, drawable, saida, saida, 0, 9, 1, 1, 1, 1, 1)
        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())

Gimp.main(ExportPlugin.__gtype__, sys.argv)

Cada execução cria out_NNN.png com índice incremental — útil para empilhamento de etapas em pipelines.

Exemplo 5 — Plugin com UI customizada (dialog GTK)

from gi.repository import Gimp, GLib, Gtk

class ResizePlugin(Gimp.PlugIn):
    def do_query_procedures(self):
        return ["resize-dialog"]

    def do_set_i18n(self, name):
        return False

    def do_create_procedure(self, name):
        procedure = Gimp.ImageProcedure.new(self, name,
                                            Gimp.PDBProcType.PLUGIN,
                                            self.run, None)
        procedure.set_image_types("*")
        procedure.set_menu_label("Redimensionar com Dialogo")
        procedure.add_menu_path('<Image>/Image/Scale/')
        return procedure

    def run(self, procedure, run_mode, image, drawables, config, run_data):
        if run_mode == Gimp.RunMode.INTERACTIVE:
            return self.run_interactive(procedure, image)
        return self.run_noninteractive(procedure, image)

    def run_interactive(self, procedure, image):
        dialog = Gtk.Dialog(title="Redimensionar")
        dialog.add_button("Cancelar", Gtk.ResponseType.CANCEL)
        dialog.add_button("OK", Gtk.ResponseType.OK)
        entry = Gtk.Entry()
        entry.set_text("800")
        dialog.get_content_area().add(entry)
        dialog.show_all()
        response = dialog.run()
        if response != Gtk.ResponseType.OK:
            dialog.destroy()
            return procedure.new_return_values(Gimp.PDBStatusType.CANCEL, GLib.Error())
        nova_largura = int(entry.get_text())
        dialog.destroy()
        return self._resize(procedure, image, nova_largura)

    def _resize(self, procedure, image, nova_largura):
        proporcao = nova_largura / image.get_width()
        nova_altura = int(image.get_height() * proporcao)
        pdb.gimp_image_scale_full(image, nova_largura, nova_altura,
                                  Gimp.InterpolationType.CUBIC)
        Gimp.displays_flush()
        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())

Gimp.main(ResizePlugin.__gtype__, sys.argv)

Usa Gtk.Dialog para entrada interativa. Em modo não-interativo, o plugin pode ser chamado com argumentos pre-definidos via PDB.

Compilação (plugin C)🔗

EtapaComando
Headerspkg-config --cflags libgimp-2.0
Bibliotecaspkg-config --libs libgimp-2.0
Buildgcc -o meu_plugin $(pkg-config --cflags libgimp-2.0) meu_plugin.c $(pkg-config --libs libgimp-2.0)
Installgimptool-2.0 --install meu_plugin.c (atalho)

Em sistemas baseados em Arch, instale gimp-devel (ou libgimp-devel) para obter os headers libgimp/gimp.h.

Diretórios de Instalação🔗

PlataformaPlugin PythonPlugin C
Linux~/.config/GIMP/2.10/plug-ins/<nome>/<nome>.py~/.local/lib/gimp/2.0/plug-ins/<nome>/<nome>
macOS~/Library/Application Support/GIMP/2.10/plug-ins/<nome>/<nome>.py~/Library/Application Support/GIMP/2.0/plug-ins/<nome>/<nome>
Windows%APPDATA%\GIMP\2.10\plug-ins\<nome>\<nome>.py%PROGRAMFILES%\GIMP 2\lib\gimp\2.0\plug-ins\

Importante: o nome da pasta deve coincidir com o nome do arquivo (sem extensão). No Linux/macOS, tanto o arquivo Python quanto o binário C precisam de permissão de execução (chmod +x).

Referências🔗