Thursday, September 24, 2009

Filter tips (no Alistair)

I was bored of repeatedly applying my PAL and VHS effects to images by hand. It was a several stage process and rather fiddly: I desperately wanted to automate it. I knew it was possible to extend The GIMP by writing your own features in Python, so I decided to have a go and see how I got on.

The documentation for writing plug-ins in Python for The GIMP was pretty well hidden, but eventually I found it here. It was well written, very easy to follow, but it looked very old. For safety's sake I felt I needed to have a hunt around and see if there were any more recent examples of filters for the GIMP in Python I could find just in case anything had changed. The tutorial seemed to have been written for The GIMP 1.5 but on my computer I'm currently using The GIMP 2.6.

Although I did try Google, the best example of Python filters for the latest version of Python were installed with The GIMP itself and sitting in:

/usr/lib/gimp/2.0/plug-ins

Sure enough, the filters in there that shipped with The GIMP 2.6 had a much better way of preserving The GIMP's state before and after the filter is applied and help undo to work and also contained the gettext function that ensures your filter can be translated into other languages. There is also a slightly changed way of specifying which menu the plug-ins show up in in The GIMP.

Writing the plug-in itself was very easy indeed. No stretching, no unpleasant bending and the gedit text editor that comes with the GNOME desktop on Ubuntu GNU/Linux was all the equipment I needed.

Writing filter in gedit

I found using the Browse... button on the Python-Fu console in The GIMP was extremely handy. It brings up a Procedure Browser which I used for finding the functions I wanted to call and their syntax. It also showed me the constants I could use, which greatly reduced the number of "magic numbers" in my code.

Procedure Browser from Python-Fu console

The basic idea is that anything you can do in The GIMP with a mouse has a matching pdb (procedure database) function, so it's really easy to write a macro-style filters - you just find the right function using Browse.. from the Python-Fu console and string them together. But as that because Python is a ridiculously easy language, it's possible to do so much more than that. One thing I didn't expect is that pdb functions sometimes have extra parameters that you can't normally access using The GIMP itself.

The second part of your filter is a call to a function called "register" in which you specify the interface for your filter, its description and where you want it to appear in the application.

A filter's interface is specified in its register function

The main problem I had was not writing the filters themselves but getting them to show up in The GIMP's menu of filters. Firstly I needed to work out where to put the filters - with Ubuntu Linux the best place is in your home directory under .gimp-2.6/plug-ins.

But putting it in the right place wasn't enough - there were two other issues. First, if you don't set your Python scripts to "Allow executing file as program" they won't show up in The GIMP. No warning, no nothing - if you forget to do that you just won't see them.

Don't forget to allow your filter to execute as a program

Secondly, you have to prefix your filter name with "python-fu-", or again it will silently refuse to show up.

Once I did get the filter to appear and, better than that, it worked, it was an amazing feeling of achievement. It's tremendously satisfying to customise a program to do some special things that you want it to do.

Success at last - click to enlarge

I've released both filters under the GPL v3, and they're available to download from here.

No comments: