Table of Contents

go back

Gimp

Gimp is a libre and gratis program to do photo editing and drawing. It is powerful with a strong a vibrant community.

Gimp also allows to use scripting in Scheme or Python2 to add functionalities, and most of the tutorial one can find on the web are directed to this idea: to have a new element in the menus that give you the functions you implemented yourself.

In this page instead we focus on how to call your functions from the command line to apply them in bulk to many pictures.

Intro

The main obstacle is that Gimp scripts are meant to be called from inside Gimp. In the normal python2 interpreter the call from gimpfu import * will fail.

To make Gimp load our script we need to embed a bit of python code in the command line.

Here is how it would be possible if the script is called batch.py. it's in the current directory, its main function is called run whose only argument is a directory name.

$ gimp -idf --batch-interpreter python-fu-eval -b 'import sys;sys.path=["."]+sys.path;import batch;batch.run("./images")' -b 'pdb.gimp_quit(1)'

Using if __name__ == '__main__': and __file__ is possible to make the python script self-contained just using subprocess to execute gimp with the needed command line.

What functions should I call?

In Gimp is the documentation of all the functions one can use. The documentation is in the HelpProcedure browser. Usually the functions are named in a quite straightforward manner; seek for the name you find in the menus or the name of the menus themselves. For example, if you want the artistic filter “cubism”, typing cubism gives plug-in-cubism.

To call the procedures one need to know that, in python2, the functions are under the object pdb (procedures database), the hyphens in the name are replaced with underscores, and the parameter run-mode has to be skipped because it is implicit.

What is a drawable?

Drawables are channels and layers. The drawable may correspond with the whole image, but functions often need both.

Example Script

Now the script should be readable. The function run will be executed in each file inside the direction passed to run (images if using the previous command line).

#!/usr/bin/python2

import os, glob, sys, time, subprocess

#if __name__ == "__main__":
#        use subprocess to start gimp and return

from gimpfu import *

def process(infile):
        print "Processing file %s " % infile
        image = pdb.gimp_file_load(infile, infile, run_mode=RUN_NONINTERACTIVE)
        drawable = image.active_layer

        print "File %s loaded OK" % infile

        h = image.height
        w = image.width

        # do manipulation

        outfile=os.path.join('processed', os.path.basename(infile))
        outfile=os.path.join(os.path.dirname(infile), outfile)
        print "Saving to %s" % outfile
        pdb.gimp_file_save(image, drawable, outfile, outfile)
        print "Saved to %s" % outfile
        pdb.gimp_image_delete(image)


def run(directory):
        start=time.time()
        print "Running on directory \"%s\"" % directory
        for infile in glob.glob(os.path.join(directory, '*')):
                process(infile)
        end=time.time()
        print "Finished, total processing time: %.2f seconds" % (end-start)

References

Gimp documentation Stack overflow answer with the original script