//log//

About

Lost in transit.
Moving.
Returning.
You're welcome.

gimp hacks: writing plugins using python

One of many amazing features that The Gimp is providing is the capability of being extensible using quite an amount of languages which aren’t too unlikely to be around on a GNU/Linux or Unix environment where Gimp mainly is to be found. Even though I don’t really often reach the point where standard Gimp features don’t suffice anymore, the idea of being able to build custom extensions at least for automating certain frequently appearing tasks is tempting. That’s why, after all, I spent some moments figuring out how to exactly get that done…

What to say:

  • You should, of course, have current installations of Gimp and Python handy and usable. Mine is Gimp 2.2.2 and Python 2.3 atop Debian sid. Depending on your distribution or operating system, you might need to explicitely install the Python package for Gimp (pygimp or gimp-python on Debian) as it may not be installed by default.
  • It’s a good idea to have some basic understanding of how Python programming is like, even though you will find that using Python to build Gimp plug-ins is pretty straightforward once you figured out a few things.
  • You should, also of course, have gone through some basic work with the Gimp to know what it is able to do and how you get some things done. This way, it will be way easier for you at least to automate some reoccuring work steps using a script..
  • It really helps, additionally, to have documentation of pygimp and the Gimp itself installed and viewable. Those you will need quite often, especially while getting started, so having them around is going to save you some troublesome minutes…

Quick Start – “Hello Gimp”

To easily get started, let’s learn to do a _very_ simple plugin in the tradition of possibly all the books on programming this world has to offer: This short piece of code shall make Gimp say “Hello Gimp” whenever the user desires it to do so:


---snip---

#!/usr/bin/env python
from gimpfu import *

def hellogimp():

   print "Hello Gimp!"

register(
   "python_fu_hellogimp", #1
   "HelloWorld plugin for Gimp",
   "HelloWorld plugin for Gimp",
   "Kristian Rink",

   "Kristian Rink",
   "2005",
   "<Toolbox>/Xtns/Python-Fu/z428/HelloGimp", #2
   "RGB*,GRAY*", #3
   [],

   [],
   hellogimp) #4
main()

---snip---

That’s already about it. Put this to a meaningfully named file into your /.gimp(Version)/plug-ins/ folder and mark it executable. Then, open a new terminal and, being there, start the Gimp (probably using the “gimp” command). It is essential that you start it this way because the “Hello World” output will go to the terminal and so be lost if you start Gimp using, for example, your menu system.

Once then the Gimp is up and running, check the “Xtns” menu in its toolbox, go to “Python-Fu”, then to “z428”, select “HelloGimp” and – be amazed to see a “Hello Gimp” written to the terminal you used to start Gimp. Congratulations, you just added (though quite useless) functionality to the Gimp using pygimp! Now this is a good place to mention that, in case something went wrong and your Gimp is not outputting “Hello Gimp” but just an error and a python stack trace, you can re-edit the plugin code, write it and execute it from within the Gimp without restarting the application itself – this only becomes necessary whenever you messing around with the register() function and, so, the interface of the plugin function.

Let’s take a short look at what we got, by now:

  • First of all, you need to start your plug-in the way you’d start each other python script, too, by specifying the #! followed by the path to your python interpreter binary.
  • Of course, then, you have to make sure your code has the Gimp/python connectivity available. Do that by importing things from the gimpfu module.
  • Then, a small function to actually do something is generated. In this example, though, the only thing it does is to print out the string “Hello Gimp”… Of course later you might want to make up more useful functions, same as you’re able to put a couple of such functions into one plugin file.
  • Then, you call “register()” for your function to make it known to the Gimp. The parameters it takes are in length explained in the pygimp documentation; some, however, are of special interest:
    • #1 is the name that function will have when registered with the Gimp. This is how other plugins same as the Gimp itself will access your code, same as you will find it listed in the Gimp’s procedure browser.
    • #2 specifies where in the menu structure the entry for your plugin should be created.
    • #3 gives a hint which sorts of pictures (here: RGB-colored and grayscale ones) the plugin may operate on
    • #4, finally, is the name of the function to register; in this example, this is the hellogimp() we defined a few lines earlier..
  • Finally, you have to call main() to actually get the plugin started. In there, everything will happen that is necessary to get your plugin running, to possibly display a user interface, to call functions when needed and so on.

If all went fine, besides seeing the “Hello Gimp” string you’ll also be able to gather information about the presence of your plug-in in several places within Gimp:

  • In “Xtns” menu of the Gimp toolbox you’ll find the Plugin Browser which enables you to look at what plugins your Gimp currently knows about. Simply enter “Hello” into the search field and see what happens…
  • Also found in “Xtns” and way more crucial for your future work of writing Gimp plugins is the Procedure Browser where you can find information about, well, procedures that are available (read: callable) within your Gimp installation. These include both core Gimp functionality (enter “gimp_” into the search field and see) and stuff provided by plugins, scripts and the like. These functions you’re likely to use while creating plugins of your own. Enter “python_” into the search field to see a list of all python-fu functions, including python_fu_hellogimp…

A more useful example

An effect I am frequently using for blurring images is done more or less like this:

  • Create a copy of a picture (which basically is a copy of the pictures background layer) and desaturate it.
  • Do a Gaussian blur on that copied layer.
  • Switch its overlay mode to “addition”
  • Flatten the image.

Since this is pretty straightforward and works without a lot of tuning or user interaction, it’s possibly a good thing to get started with while creating a first plugin that actually _does_ something. Here we go:


---snip---

#!/usr/bin/env python
from gimpfu import *

def mergesofned(cimage,clayer):
   worklayer=clayer.copy()

   worklayer.name="BLUR"
   worklayer.mode=ADDITION_MODE
   cimage.add_layer(worklayer,0)
   pdb.gimp_desaturate(worklayer)

   pdb.plug_in_gauss_rle(cimage,worklayer, 10, 15, 15)
   myimage.flatten()

register(
   "python_fu_mergesofned",
   "merge picture with a blurred version of itself",
   "merge picture with a blurred version of itself",
   "Kristian Rink",
   "Kristian Rink",

   "2005",
   "<Image>/Python-Fu/z428/LayeredSoftness",
   "RGB*,GRAY*",
   [],
   [],

   mergesofned)

main()
---snip---

You probably couldn’t help noticing that it’s indeed a little more complicated than the HelloGimp example. Also let’s go through this one step by step:

  • Overally and at first, I hope you see the base structure of importing gimpfu, defining a plugin function, registering it and calling main(), like in the previous example.
  • You also might see that the working function in this one, mergesofned(cimage,clayer), requires two parameters (cimage = the image currently working, clayer = the currently active layer). By now, all you need to know is that they’re provided to your function by the Gimp and the python layer that is including your plugin into it.
  • You might have noticed that “cimage”, “cylayer” and “worklayer” (copy of clayer that is created within the mergesofned() function) are treated as objects for example by calling member functions (copy()) or setting properties (mode). These objects (image, layer, channel, drawable, tile, pixel region) are provided by pygimp and extensively covered in its documentation.
  • Furthermore, there are two calls (gimp_desaturate() and plug_in_gauss_rle()) that might remind you of what you saw while using the Gimp Procedure Browser. Indeed, here you see how to access those procedures from inside a custom plugin: There’s an object pdb (procedure database) which you use to access any sort of Gimp-given functionality by specifying the name of the function (which you find in the procedure database using the Procedure Browser) and parameters it neesdd (which you also will learn about using the Procedure Browser).
  • If, by now, you look at the mergesofned() function and compare this with the workflow for the desired effect pointed out before, you’ll see that the script is pretty self-explaining, leaving aside that you have to find out the names for the functions to use instead of manually calling the required functionality.
  • Finally, you see that this time the plugin is not placed within the Toolbox menu but within the menu you see inside a Gimp image window, and, right there, inside Python-Fu -> z428. In this situation, this is useful because the plugin is about to operate on a given picture, anyhow, so there’s no need to have it callable without having any image opened (like we did with HelloGimp).

So overally, we’re finished pretty quickly. Did it hurt? Good, no matter whether the answer was “yes” or “no”. :] Seriously: You just read how to create basic plug-ins for the Gimp using Python and pygimp. There are lots and lots of things you can do with that, and lots and lots of things that might be interesting to show, but those all are pretty straightforward once you got the basic idea.

Where to go from here?

If you’re right now about to get something of your own to work with Gimp, you should…

  • … have the pygimp documentation handy (and possibly read it) to learn more about what can be done with the objects provided by it, like, for example, to create new images, create new layers and all such.
  • … read through the Python library reference to see what features Python does provide and how to use some of them with the Gimp.
  • … have a few looks at the Procedure Browser of Gimp to learn about its core functionalities and how to use them.
  • … play with functions that require parameters specified in register() to see how pygimp automatically creates a GUI asking the user to specify those.

So good luck for projects of your own using pygimp. As time goes by, maybe I will post more ideas and examples of how to use pygimp for certain things; meanwhile, feel free to post comments, recommendations, hints and rants as you feel appropriate.

Links:

pygimp
the Gimp
Python

22. Mai 2005

Filed under:

english , graphics