DEV Community

Alexandre
Alexandre

Posted on

Criando plug-in em c para gimp

Bem, hoje vamos criar um plug-in em c para automatizar algumas tarefas repetitivas e chatas.

Antes de começar fazer o código, é necessário instalar o gimptool.

Então, vamos instalar ele.

Instalando o gimptool

Antes de continuarmos, tenho que esclarecer que eu vou fazer isso em Linux, pois eu não uso o Window, então se você não sabe onde achar o gimptool para Window.

Mas não se preocupe, eu vou te ajudar onde pode estar esse gimptool no Window, de acordo com strontic, Ele diz que o arquivo pode está localizado no C:\program files\GIMP 2\bin\gimptool-2.0.exe.

Então, se você conseguiu localizar o arquivo, com isso, você já pode partir para a criação de plug-in.

Agora vamos instalar o Gimptool no Linux, no caso Ubuntu/Debian.

Basta ir ao terminal executar o comando: sudo apt install libgimp2.0-dev.

Pronto, é só isso, agora vamos criar um plug-in.

Criando um plug-in

Beleza, antes de criar o plug-in, eu vou explicar o eu vou fazer.

Para não dificultar o processo de aprendizado, eu vou fazer um plug-in bem simples, mas bem simples mesmo.

É basicamente colocar uma guide(guia).

Se você não sabe o que é guide. Abra o gimp e vá ao menu "Image" Ou "Imagem", se estiver português, e verá ele aí.

Passando o mouse em cima, você verá 4 opções.

Aqui está uma captura de tela.

Localização do guide

Clicando na primeira opção, vai aparecer uma tela para escolher a direção e inserir um valor da posição da guia.

Então, colocando na direção vertical e posição 50%, vai aparecer uma linha azul no meio da imagem, por exemplo, nessa captura de tela.

A linha azul de guia

Eu quero automatizar isso, pois é chato fica abrindo a telinha e inserindo os valores.

Então, primeiro, vamos criar um arquivo chamado add_guias.c.

Eu vou colocar o código inteiro logo de vez para fazer um teste, e então, depois vou explicando ao pouco.

#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,
    run
};

static void query (void) {

  static GimpParamDef args[] = {
    {
      GIMP_PDB_INT32, // Tipo de variável
      "run-mode", // Nome da variável
      "Run mode" // Descrição da variável
    },
    {
      GIMP_PDB_IMAGE, // Tipo de variável
      "image", // Nome da variável
      "Input image" // Descrição da variável
    },
    {
      GIMP_PDB_DRAWABLE, // Tipo de variável
      "drawable", // Nome da variável
      "Input drawable" // Descrição da variável
    }
  };

  gimp_install_procedure (
    "plug-in-add_guias", // Nome do procedure
    "Adiciona guia", // Uma pequena descrição do que o procedure faz
    "Ele adiciona uma guia no meio da imagem", // Uma descrição completa
    "Alexandre dos Santos Alves", // Seu nome
    "Copyright Alexandre", // Licença
    "2023", // Ano que foi criado
    "_Adicona Guia", // Nome que vai aparece no menu
    "RGB*, GRAY*", // Tipo de imagem que o procedure vai trabalhar
    GIMP_PLUGIN, // Tipo de procedure
    G_N_ELEMENTS (args), // Tamanho do parâmetro
    0, // Tamanho do retorno
    args, // o parâmetro do procedure
    NULL); // o retorno do procedure.

  gimp_plugin_menu_register ("plug-in-add_guias",
                               "<Image>/Tools/");
}

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

    // A variável que vai ser retornado
    static GimpParam  values[1];
    GimpPDBStatusType status = GIMP_PDB_SUCCESS; 
    GimpRunMode       run_mode;
    GimpDrawable     *drawable;

    /* Definindo valores de saída obrigatórios    */
    *nreturn_vals = 1;
    *return_vals  = values;

    /* É obrigatório isso */
    values[0].type = GIMP_PDB_STATUS;
    values[0].data.d_status = status;

    run_mode = param[0].data.d_int32;
    gint image = param[1].data.d_image;
    drawable = gimp_drawable_get(param[2].data.d_drawable);

    gdouble metade_do_tamanho_da_image = (gimp_image_width(image) * 0.5);

    gimp_image_add_vguide(image, metade_do_tamanho_da_image);

    gimp_displays_flush ();
}

MAIN()
Enter fullscreen mode Exit fullscreen mode

Com esse código, copie e cole no arquivo e execute o comando no qual o arquivo está localizado.

Se for Window, C:\program files\GIMP 2\bin\gimptool-2.0.exe --install add_guias.c.
Se for Linux, gimptool-2.0 --install add_guias.c.

Se por acaso, aparecer isso aqui embaixo, pode ignorar.

add_guias.c:92:2: warning: ‘gimp_drawable_get’ is deprecated: Use 'gimp_drawable_get_buffer' instead [-Wdeprecated-declarations]
   92 |  drawable = gimp_drawable_get(param[2].data.d_drawable);
      |  ^~~~~~~~
In file included from /usr/include/gimp-2.0/libgimp/gimp.h:41,
                 from add_guias.c:1:
/usr/include/gimp-2.0/libgimp/gimpdrawable.h:52:16: note: declared here
   52 | GimpDrawable * gimp_drawable_get                    (gint32         drawable_ID);
      |                ^~~~~~~~~~~~~~~~~
Enter fullscreen mode Exit fullscreen mode

Se não houver erro, além desse aviso, agora, ele vai aparece no Gimp, então feche o Gimp e abra novamente e você verá no menu Tools(Ferramentas) um item com nome Adiciona Guia.

Crie uma nova imagem e clique nele para ver o que acontece.

Bem, Se apareceu a linha azul, então ele funcionou, se não, aí é com você para resolver.

Mentira, comente no comentário, o problema.

Mas, agora, vamos entender o código.

Na primeira linha, estamos incluindo uma biblioteca essencial para construção do plug-in, então não tem muito o que explicar sobre isso.

Em baixo disso, podemos ver duas funções, query e run.

...

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,
    run
};

...
Enter fullscreen mode Exit fullscreen mode

Mas antes de explicar essas funções, vamos pular essa parte e ver a variável PLUG_IN_INFO.

Essa variável pode guardar 4 valores.

Mas o que são esses valores?

São funções que o Gimp vai chamar.

Ou seja, o primeiro valor é uma função que vai ser chamado durante a inicialização do Gimp, no meu caso, eu coloquei NULL, pois não quero fazer nada durante a inicialização.

O segundo é quit, que vai ser chamado durante o fechamento do Gimp, que no meu caso, está NULL.

Esses dois valores que citei, são opcionais, ou seja, não é necessário ter uma função, basta colocar NULL.

Agora os dois próximos que vou citar são obrigatórios.

O terceiro é query, não sei muito o que explicar sobre isso, pois a documentação não diz muito sobre isso, mas no meu entendimento, suponho que é usado para instalar o plug-in, mas vamos tenta entender mais, quando estivemos na dentro função query().

O quarto e último é run, é peça central do código, pois ele vai ser rodado, quando for chamado, seja pelo menu, ou pelo script fu, ou Python fu.

Agora, sabendo disso, vamos partir para aquelas duas funções criada para entender os parâmetros.

static void query (void);
static void run (
    const gchar *name, // Nome do plug-in
    gint nparams, // Quantidade de parâmetro
    const GimpParam *param, // O parâmetro do plug-in
    gint *nreturn_vals, // Quantidade de retorno
    GimpParam **return_vals); // O retorno do plug-in
Enter fullscreen mode Exit fullscreen mode

Não tem muito que o explicar sobre o parâmetro do query, então vamos para run.

O primeiro parâmetro é o nome do plug-in.
O segundo é a quantidade de parâmetro.
O terceiro é o parâmetro do plug-in.
O quarto é a quantidade de retorno.
O quinto é o retorno do plug-in.

Beleza, sabendo quais são os parâmetros.

Agora, vamos entender ver o que dentro da função query(void).

static void query (void) {

  static GimpParamDef args[] = {
    {
      GIMP_PDB_INT32, // Tipo de variável
      "run-mode", // Nome da variável
      "Run mode" // Descrição da variável
    },
    {
      GIMP_PDB_IMAGE, // Tipo de variável
      "image", // Nome da variável
      "Input image" // Descrição da variável
    },
    {
      GIMP_PDB_DRAWABLE, // Tipo de variável
      "drawable", // Nome da variável
      "Input drawable" // Descrição da variável
    }
  };

  gimp_install_procedure (
    "plug-in-add_guias", // Nome do procedure
    "Adiciona guia", // Uma pequena descrição do que o procedure faz
    "Ele adiciona uma guia no meio da imagem", // Uma descrição completa
    "Alexandre dos Santos Alves", // Seu nome
    "Copyright Alexandre", // Licença
    "2023", // Ano que foi criado
    "_Adicona Guia", // Nome que vai aparece no menu
    "RGB*, GRAY*", // Tipo de imagem que o procedure vai trabalhar
    GIMP_PLUGIN, // Tipo de procedure
    G_N_ELEMENTS (args), // Tamanho do parâmetro
    0, // Tamanho do retorno
    args, // o parâmetro do procedure
    NULL); // o retorno do procedure.

  gimp_plugin_menu_register ("plug-in-add_guias", // nome do plug-in
                               "<Image>/Tools/"); // Localização dele no menu
}
Enter fullscreen mode Exit fullscreen mode

Primeiro, declaramos uma variável static GimpParamDef args[], ela possibilita saber quais são os valores do parâmetro que o plug-in recebe.

No nosso caso, vamos apenas manter o padrão, que são run-mode, image e drawable.

Mas se por acaso, seu plug-in precisa de mais valores, eu vou colocar uma lista de cada tipo de variável para facilitar para você.

Tipo de variável Descrição
GIMP_PDB_INT32 32-bit integer
GIMP_PDB_INT16 16-bit integer
GIMP_PDB_INT8 8-bit integer
GIMP_PDB_FLOAT Float
GIMP_PDB_STRING String
GIMP_PDB_INT32ARRAY Array of INT32
GIMP_PDB_INT16ARRAY Array of INT16
GIMP_PDB_INT8ARRAY Array of INT8
GIMP_PDB_FLOATARRAY Array of floats
GIMP_PDB_STRINGARRAY Array of strings
GIMP_PDB_COLOR Color
GIMP_PDB_ITEM Item ID
GIMP_PDB_DISPLAY Display ID
GIMP_PDB_IMAGE Image ID
GIMP_PDB_LAYER Layer ID
GIMP_PDB_CHANNEL Channel ID
GIMP_PDB_DRAWABLE Drawable ID
GIMP_PDB_SELECTION Selection ID
GIMP_PDB_COLORARRAY Array of colors
GIMP_PDB_VECTORS Vectors (psath) ID
GIMP_PDB_PARASITE Parasite
GIMP_PDB_STATUS Procedure return status
GIMP_PDB_END Marker for last enum value

Beleza, Já entendemos sobre o args[], agora vamos para função que estamos chamando gimp_install_procedure.

Não tem muito o que explicar, pois se você ler o comentário ao lado do parâmetro, já dá pra ter uma noção, mas o que ele basicamente faz é instalar o plug-in no gimp.

Então, vamos para outra função que é gimp_plugin_menu_register. Como o nome diz, ele vai registrar o plug-in no Menu, que no nosso caso, vai ser colocado no Tools.

Aqui nós terminamos a função query().

Vamos para função run(), por ser um código um pouco grande, eu vou colocar a explicação dentro do código.

...

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

    // A variável que vai ser retornado
    static GimpParam  values[1];

    // Como o nome diz é o status
    GimpPDBStatusType status = GIMP_PDB_SUCCESS; 

    // O run_mode é usado para saber se estar no modo interativo ou não
    // Não irei explicar isso nesse blog
    GimpRunMode       run_mode;

    // Variável que, por padrão, é o layer(camada) atual.
    GimpDrawable     *drawable;

    /* Definindo valores de saída obrigatórios    */
    *nreturn_vals = 1; // definindo o tamanho da variável values
    *return_vals  = values;

    /* É obrigatório isso */
    values[0].type = GIMP_PDB_STATUS;
    values[0].data.d_status = status;

    // Aqui temos uma forma de pegar os valores passados no parâmetro
    // Eu vou colocar lista de tipos de variáveis abaixo fora do código
    // Sobre o índices da variável 'param', ele está na mesma ordem
    // que você declarou na função 'query' da variável 'args'
    run_mode = param[0].data.d_int32;
    gint image = param[1].data.d_image;
    drawable = gimp_drawable_get(param[2].data.d_drawable);

    // Agora, a partir daqui, são os códigos que você pode fazer
    // Aqui estamos pegando a metade do tamanho da imagem
    // Para poder colocar a guia no meio
    gdouble metade_do_tamanho_da_image = (gimp_image_width(image) * 0.5);

    // essa função coloca a guia, primeiro parâmetro é a imagem
    // o segundo é a posição dessa guia
    gimp_image_add_vguide(image, metade_do_tamanho_da_image);

    // Essa função serve para atualizar o que você fez no código,
    // mas não é necessário para o nosso caso,
        // Não estamos alterando a imagem
    gimp_displays_flush ();
}

...
Enter fullscreen mode Exit fullscreen mode
Tipos de variáveis membro
gint32 d_int32
gint16 d_int16
guint8 d_int8
gdouble d_float
gchar d_string
gint32 d_int32array
gint16 d_int16array
guint8 d_int8array
gdouble d_floatarray
gchar d_stringarray
GimpRGB d_colorarray
GimpRGB d_color
gint32 d_display
gint32 d_image
gint32 d_item
gint32 d_layer
gint32 d_layer_mask
gint32 d_channel
gint32 d_drawable
gint32 d_selection
gint32 d_boundary
gint32 d_vectors
gint32 d_unit
GimpParasite d_parasite
gint32 d_tattoo
GimpPDBStatusType d_status

Se você não entendeu essa lista ou não sabe usá-la, basta fazer assim param[i].data.membro, troque o membro para um item da lista.

E por último, temos que colocar o MAIN(), é obrigatório que tenha isso, e que fique no final do arquivo.

Pronto, com isso, você tem a base para construir um plug-in por si próprio, só que não, pois você ainda não sabe quais são os métodos disponíveis no Gimp.

Aqui está a documentação do Gimp.

Agora, sim, podemos terminar aqui.

Bem, então é isso e tchau!

Top comments (0)