{"id":201,"date":"2012-12-14T10:04:39","date_gmt":"2012-12-14T08:04:39","guid":{"rendered":"http:\/\/www.joanillo.org\/?p=201"},"modified":"2020-09-16T12:41:46","modified_gmt":"2020-09-16T10:41:46","slug":"programando-con-gimp-i-ejecutar-plugins-desde-la-consola","status":"publish","type":"post","link":"https:\/\/www.joanillo.org\/?p=201&lang=es","title":{"rendered":"Programando con GIMP I. Ejecutar plugins desde la consola"},"content":{"rendered":"<p><a href=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2012\/12\/blur.jpg\"><img loading=\"lazy\" src=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2012\/12\/blur-300x232.jpg\" alt=\"\" title=\"blur\" width=\"300\" height=\"232\" class=\"alignright size-medium wp-image-699\"><\/a>Con este art\u00edculo quiero empezar una serie de posts sobre la programaci\u00f3n con <strong>GIMP<\/strong>. No es un tutorial para aprender a programar GIMP, tan s\u00f3lo es poner en orden unas cuantas ideas enfocadas a un futuro proyecto, que b\u00e1sicamente es desarrollar un framework para poder explicar historias mientras dibujas sobre la pantalla con una <em>wacom<\/em>, y donce se suceden m\u00faltiples efectos visuales y sonoros. Si esta serie de posts se acaba, en el \u00faltimo podremos ver c\u00f3mo se toca una melod\u00eda donde el pentagrama est\u00e1 dibujado sobre el GIMP y las notes las dibujo con el rat\u00f3n o la wacom.<br \/>\nAnte todo necesitamos las librer\u00edas de desarrollo del GIMP:<\/p>\n<blockquote><p>$ sudo apt-get install libgimp2.0-dev<\/p><\/blockquote>\n<p>y aprendemos a programar un plugin a partir de un tutorial que si buscas por Google seguro que encuentras:<\/p>\n<ul>\n\\t<\/p>\n<li><a href=\"http:\/\/developer.gimp.org\/writing-a-plug-in\/1\/index.html\">http:\/\/developer.gimp.org\/writing-a-plug-in\/1\/index.html<\/a><\/li>\n<\/ul>\n<p>Con este tutorial, que implementa un <strong>blur<\/strong> (difuminador) aprendemos los conceptos b\u00e1sicos de la programaci\u00f3n con GIMP. Nuestros plugins los programaremos en lenguage C. Para compilar el plugin haremos:<\/p>\n<blockquote><p>$ gimptool-2.0 &#8211;install myblur.c<\/p><\/blockquote>\n<p>Para ejecutar el plugin lo haremos des de dentro del GIMP con <strong>Filtros &gt; Difumina &gt; My Blur<\/strong>. O tambi\u00e9n lo podemos hacer con un script Script-Fu: <strong>Filtros &gt; Script-Fu &gt; Consola<\/strong><\/p>\n<blockquote><p>(plug-in-myblur run-mode image drawable)<\/p><\/blockquote>\n<p>donde sustituimos <em>run-mode<\/em>, <em>image<\/em> i <em>drawable<\/em> por los valores correctos. Por ejemplo:<\/p>\n<blockquote><p>(plug-in-myblur RUN-NONINTERACTIVE 1 2)<\/p><\/blockquote>\n<p>Pero a mi lo que me interesa es ejecutar plugins desde fuera del GIMP, desde la consola. La primera manera de hacerlo es con el lenguatge de script propio del GIMP, el lenguaje <strong>Scheme<\/strong>.<\/p>\n<p><em>example_script.scm<\/em>:<\/p>\n<blockquote><p>\n(<br \/>\ndefine (example-script inputFilename outputFileName)<br \/>\n(<br \/>\nlet* (<br \/>\n(image (car (gimp-file-load RUN-NONINTERACTIVE inputFilename inputFilename)))<br \/>\n(drawable (car (gimp-image-get-active-layer image)))<br \/>\n)<br \/>\n(plug-in-myblur RUN-NONINTERACTIVE image drawable)<br \/>\n(gimp-file-save RUN-NONINTERACTIVE image drawable outputFileName outputFileName)<br \/>\n)<br \/>\n)<\/p><\/blockquote>\n<p>Los scripts los he de guardar en la carpeta de scripts del GIMP: <em>~\/.gimp-2.6\/scripts<\/em>. Para ejecutarlo puedo invocar al GIMP en modo comando (opci\u00f3n -b):<\/p>\n<blockquote><p>$ gimp -i -b &#8220;(example-script \\\\&#8221;confirmacion.jpg\\\\&#8221; \\\\&#8221;confirmacion_out.jpg\\\\&#8221;)&#8221; -b &#8220;(gimp-quit 0)&#8221;<br \/>\nbatch command executed successfully<\/p><\/blockquote>\n<p>Pero todav\u00eda no me convence esta manera de hacer. Yo lo que quiero es poder aplicar un plugin a una imagen abierta del GIMP, ejecutando el plugin desde la consola, no desde dentro del GIMP. I la clave est\u00e1 en saber que el GIMP tiene un servidor, el <strong>servidor Script-Fu<\/strong>, que trabaja por defecte por el puerto 10008 i que escucha las peticiones TCP que le llegan de la red (socket). Primero de todo hemos de arrancar el servidor:<\/p>\n<blockquote><p>Filtres &gt; Script-Fu &gt; Inicia el servidor<\/p><\/blockquote>\n<p>y efectivamente puedo conectarme al servidor:<\/p>\n<blockquote><p>$ telnet localhost 10008<\/p><\/blockquote>\n<p>pero esto no sirve de nada si no s\u00e9 el protocolo para comunicarme con este servidor. Este protocolo est\u00e1 explicado en este enlace:<\/p>\n<ul>\n<li><a href=\"http:\/\/docs.gimp.org\/en\/gimp-filters-script-fu.htmlhttp:\/\/\">http:\/\/docs.gimp.org\/en\/gimp-filters-script-fu.html<\/a><\/li>\n<\/ul>\n<p>no es un protocolo dif\u00edcil de entender o implementar. Por suerte, en Google encontramos el script <strong>servertest.py<\/strong> que implementa este protocolo. Por ejemplo lo podemos encontrar en uno de estos enlaces:<\/p>\n<ul>\n<li><a href=\"http:\/\/code.ohloh.net\/file?fid=P0nRNyEugGcSvUxVURQKblLqPI0&amp;cid=TqzJ3ucHvvE&amp;s=&amp;browser=Default#L0\">http:\/\/code.ohloh.net\/file?fid=P0nRNymevaEugGcSvUxVURQKblLqPI0&amp;cid=TqzJ3ucHvvE&amp;s=&amp;browser=Default#L0<\/a><\/li>\n<li>mi wiki: <a href=\"http:\/\/wiki.joanillo.org\/index.php\/Programaci%C3%B3_GIMP#Servidor_Script-Fuhttp:\/\/\">http:\/\/wiki.joanillo.org\/index.php\/Programaci%C3%B3_GIMP#Servidor_Script-Fu<\/a><\/li>\n<\/ul>\n<p>Ahora ya puedo ejecutar mi plugin desde la consola:<\/p>\n<blockquote><p>$  python servertest.py<br \/>\nTrying ::1.<br \/>\nTrying 127.0.0.1.<br \/>\nScript-Fu-Remote &#8211; Testclient<br \/>\n&gt; (plug-in-myblur RUN-NONINTERACTIVE 1 2)<br \/>\n(OK): Success<br \/>\n&gt;<\/p><\/blockquote>\n<p>servertest.py trabaja de forma interactiva. No me convence. Hago una modificaci\u00f3n de manera que pueda trabajar de forma totalment desatendida: script <strong>servertest_v2.py<\/strong> (<a href=\"http:\/\/wiki.joanillo.org\/index.php\/Programaci%C3%B3_GIMP#Servidor_Script-Fu\">http:\/\/wiki.joanillo.org\/index.php\/Programaci%C3%B3_GIMP#Servidor_Script-Fu<\/a>)<\/p>\n<blockquote><p>$ python servertest_v2.py localhost 10008 &#8220;(plug-in-myblur RUN-NONINTERACTIVE 1 2)&#8221;<br \/>\nHOST: localhost<br \/>\nPORT: 10008<br \/>\nCOMMAND: (plug-in-myblur RUN-NONINTERACTIVE 1 2)<br \/>\nTrying ::1.<br \/>\nTrying 127.0.0.1.<br \/>\n(plug-in-myblur RUN-NONINTERACTIVE 1 2)<br \/>\n(OK): Success<\/p><\/blockquote>\n<p>Es decir, ejecuto el anterior comando desde la consola, y de forma m\u00e1gica la imagen que tengo abierta en el GIMP queda difuminada.<\/p>\n<p>Ahora s\u00f3lo falta ejecutar esta comando no desde la consola, sino desde un ejecutable de C, que es mi lenguaje de referencia para desarrollar futuros proyectos:<\/p>\n<blockquote><p>\/\/ gcc -o execute_blur execute_blur.c<br \/>\nint main(int argc, char *argv[])<br \/>\n{<br \/>\n\\tsystem(&#8220;python servertest_v2.py localhost 10008 \\\\&#8221;(plug-in-myblur RUN-NONINTERACTIVE 1 2)\\\\&#8221;&#8221;);<br \/>\n}<\/p><\/blockquote>\n<blockquote><p>$ .\/execute_blur<\/p>\n<p>HOST: localhost<br \/>\nPORT: 10008<br \/>\nCOMMAND: (plug-in-myblur RUN-NONINTERACTIVE 1 2)<br \/>\nTrying ::1.<br \/>\nTrying 127.0.0.1.<br \/>\n(plug-in-myblur RUN-NONINTERACTIVE 1 2)<br \/>\n(OK): Success<\/p><\/blockquote>\n<p>y la imagen que tengo abierta en el GIMP queda difuminada.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Con este art\u00edculo quiero empezar una serie de posts sobre la programaci\u00f3n con GIMP. No es un tutorial para aprender a programar GIMP, tan s\u00f3lo es poner en orden unas cuantas ideas enfocadas a un futuro proyecto, que b\u00e1sicamente es desarrollar un framework para poder explicar historias mientras dibujas sobre la pantalla con una wacom, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[324,194],"tags":[],"_links":{"self":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/201"}],"collection":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=201"}],"version-history":[{"count":1,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/201\/revisions"}],"predecessor-version":[{"id":202,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/201\/revisions\/202"}],"wp:attachment":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}