Programando con GIMP II. Pintar pixels en la pantalla

La verdad es que no hay mucha información y ejemplos para programar plugins con GIMP. Pero lo cierto es que la librería está bien documentada y se entiende bastante rápido si uno está familiarizado con la programación de otras APIs y con los conceptos de GIMP (capas, brushes,…).

GIMP Library Reference Manual:

A modo de ejemplo vamos a hacer lo que consideramos más básico: pintar pixels individuales sobre la pantalla. Del anterior enlace haremos un repaso a las diferentes posibilidades que nos ofrece la librería y nos fijamos en la siguiente entrada:

gimppixelfetcher — Functions for operating on pixel regions:

y aquí tenemos unas pocas funciones, concretamente la que necesitaremos para pintar pixels es

void gimp_pixel_fetcher_put_pixel (GimpPixelFetcher *pf,
gint x,
gint y,
const guchar *pixel);

el primer argumento es un puntero a un objeto GimpPixelFetcher que hemos inicializado previamente.

\tGimpPixelFetcher *pf;
\tpf = gimp_pixel_fetcher_new (drawable,FALSE);

Se inicializa a partir del drawable, que representa la capa sobre la que queremos pintar. Por tanto este puntero nos da un espacio de memoria que podem asociar a un pixel de una capa.

Los argumentos x, y son evidenmente las coordenadas donde queremos escribir el pixel.

Finalmente el puntero *pixel contiene la información del pixel, concretamente los 3 componentes del color.

Seguidamente mostramos la función principal pintar_pixel() de nuestro plugin, que lo que hace es pintar 5 pixels por pantalla, en las posiciones (20,0),…, (24,0). El código (fitxer gimp_pixel_fetcher_put_pixel.c) lo puedes descargar de la wiki, aunque está un poco sucio. El primer pixel tendrá el mismo color que el foreground que tengo seleccionado en ese momento; para el segundo pixel establezco un color con la función gimp_rgb_set(); el tercer pixel será igual que el pixel de la posición (0,0), utilizo la función gimp_pixel_fetcher_get_pixel(); para los cuarto y quinto pixel pongo directamente las coordenadas RGB del color.

Para compilar:

$ gimptool-2.0 –install gimp_pixel_fetcher_put_pixel.c

y el código:

static void pintar_pixel (GimpDrawable *drawable)
{
\tGimpPixelFetcher *pf;
\tgint x1, y1;
\tguchar *px; //pixel is an array of bpp bytes.
\tGimpRGB color;

\tx1=0;
\ty1=0;

\tpf = gimp_pixel_fetcher_new (drawable,FALSE);
\tpx = g_new (guchar, 1);

\t//1. escribo un pixel con el color del foreground
\tgimp_context_get_foreground (&color);
\t//g_message («%d,%d,%d»,(int)(&color)->r,(int)(&color)->g,(int)(&color)->b);
\tpx[0] = 255*(&color)->r; //rojo (0-255)
\tpx[1] = 255*(&color)->g; //verde (0-255)
\tpx[2] = 255*(&color)->b; //azul (0-255)
\tgimp_pixel_fetcher_put_pixel (pf, x1+20, y1, px);

\t//2. escribo un pixel y digo qué color quiero con la función gimp_rgb_set
\tgimp_rgb_set (&color, 0.0, 1.0, 1.0);
\tpx[0] = 255*(&color)->r; //rojo (0-255)
\tpx[1] = 255*(&color)->g; //verde (0-255)
\tpx[2] = 255*(&color)->b; //azul (0-255)
\tgimp_pixel_fetcher_put_pixel (pf, x1+21, y1, px);

\t//3. escribo un pixel igual que el de la posición (0,0)
\tgimp_pixel_fetcher_get_pixel (pf,x1, y1, px);
\t//g_message («%d,%d,%d»,(int)px[0],(int)px[1],(int)px[2]); //puedo obtener información del pixel (componentes RGB)
\tgimp_pixel_fetcher_put_pixel (pf, x1+22, y1, px);

\t//4. escribo un pixel y digo qué color quiero
\tpx[0] = 255; //rojo (0-255)
\tpx[1] = 0; //verde (0-255)
\tpx[2] = 0; //azul (0-255)
\tgimp_pixel_fetcher_put_pixel (pf, x1+23, y1, px);
\t// o bé
\t*px=0; //rojo (0-255)
\t*(px+1)=0; //verde (0-255)
\t*(px+2)=255; //azul (0-255)
\tgimp_pixel_fetcher_put_pixel (pf, x1+24, y1, px);

\tg_free (px);

\tgimp_pixel_fetcher_destroy (pf);

\tgimp_drawable_flush (drawable);
\tgimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
\tgimp_drawable_update (drawable->drawable_id,20,0,5,1);

}