Writing Python script for Gimp

Yesterday I needed to create a bunch of identical icons, but with different numbers. I still haven’t come up with a final design of the icons, but I needed something to put in my application. So I decided to create really simple template icon in Gimp (open-source image editor, aka Free Photoshop) and then just manually edit and create all the icons.

When I created 3 images, I realized that, if I will need to change the design of icons, I would have to manually create all the icons again (In total I need 29 icons, don’t ask me why). That’s a crappy work that requires some automation.

I started to google the way to script it, and I found out that I can write a script in Python. And that was super great, because I love Python :).

The process of scripting Gimp is really straightforward, but requires some googling to build a complete picture (I will try to save you some time with this post):

  1. Create directory for your scripts
  2. Tell Gimp where to look for your scripts
  3. Create crappy-job-automatization-script.py in the directory.
  4. Run terminal and tell GIMP what to do.

Below I will describe the process in details. I’m doing all this on Mac, but I believe that differences are not very significant.

1. Creating directory for your scripts

I really like Unix approach to store application settings as hidden files inside a user’s home directory. So let’s create a hidden directory for Gimp scripts. Usually, its .gimp2-6/scripts, but I don’t like to explicitly write application version, so I just named it .gimp/scripts.

Run in terminal:

mkdir -p ~/.gimp/scripts

2. Telling Gimp where to look for your scripts

  • Run Gimp
  • Select from menu Edit->Preferences
  • Expand Folders
  • Select Scripts and add your scripts directory

Note: You probably noticed that there is already created folder for scripts in /Library. You can use it without any problems, just I like when everything is in my home directory.

3. Creating icon_generator.py in the directory.

In the script directory create a file and insert the following code (You can find an updated version of the script on GitHub):

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

def run(*args):
    """Generated icons with different numbers using template"""
    template_name, num, prefix, output_dir = args

    output_dir = os.path.expanduser('~/' + output_dir)
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    for i in xrange(1, num+1):
        im = pdb.gimp_file_load(template_name, template_name)

        # Suppose the name of layer in 'Text'
        text_layer = filter(lambda x: x.name == 'Text', im.layers)[0]
        pdb.gimp_text_layer_set_text(text_layer, str(i))

        # We can save only one layer at time
        # Merger visible layers in one
        merged = pdb.gimp_image_merge_visible_layers(im, 0)

        output_filename = "%s%d.png" % (prefix, i)
        full_output_filename = os.path.join(output_dir, output_filename)

        pdb.file_png_save_defaults(im, merged, full_output_filename, full_output_filename)

    print "Finished"

register(
    "chobo_icon_gen", "", "", "", "", "",
    "<Toolbox>/Xtns/Languages/Python-Fu/_Chobo Scripts/_Icon Generator", "",
    [
    (PF_FILE, "arg0", "Template file", ""),
    (PF_INT,    "arg1", "Maximum number of icons to create", 29),
    (PF_STRING, "arg3", "Output file prefix", ""),
    (PF_STRING, "arg4", "Output directory (relative to user's home)", ""),
    ],
    [],
    run
    )

main()

I will provide some analysis of the script later.

4. Running the script

You have two ways for running the script:

  1. From GUI.
  2. From terminal in batch mode.

1. Running from GUI

From menu select Filter -> Python-Fu -> Chobo Scripts -> Icon Generator, and you’ll see following dialog window.

This is where all that arguments stuff shines. During the registration you told GIMP that Template file argument is of FILE type, and now Gimp renders a corresponding control, that allows you to pick a file. Now select a template file, and run.

Note: You don’t have to restart Gimp, in order to apply the script changes. Nice.

2. Running from terminal

First, you must find the actual Gimp executable. There are two ways to obtain Gimp: build using MacPorts and download from official web site. If you’ve used the latter method, like me, you can find gimp in /Applications/Gimp.app/Contents/Resources/bin (If not, you’re gimp is already in PATH).

cd /Applications/Gimp.app/Contents/Resources/bin

./gimp –no-interface –verbose –batch ‘(python-fu-chobo-icon-gen RUN-NONINTERACTIVE “/path/to/your/icon_template.xcf” 29 “icon-” “output”)’ –batch ‘(gimp-quit 1)’

As you can see, we invoked your script using python-fu-chobo-icon-gen function. Actually, here we’re using a Scheme syntax, the other language, that you can use for Gimp Scripting. So it’s just a simple function call with 5 arguments. First argument (RUN-NONINTERACTIVE) just tells Gimp, that we’re running the script no from GUI, and is ignored by scripts.

The name, we used for registration (chobo_icon_gen), is prefixed with python-fu-, and modified to conform Scheme syntax.

The next batch command tells Gimp to quit.

Script Analysis

Method run executes all logic of the script, let’s analyse it in some details. It accepts 4 arguments:

  • template filename
  • number of icons to generate. Script will generate icons in range [1, 29].
  • output file prefix, which will be added to each generated icon filename.
  • output directory. Directory will be created if case it doesn’t exist.

In order to generate one icon the script does following:

1. Loads the template image.

im = pdb.gimp_file_load(template_name, template_name)

2. Finds a layer, named “Text”, and changes it’s text to some value.

text_layer = filter(lambda x: x.name == 'Text', im.layers)[0]
pdb.gimp_text_layer_set_text(text_layer, str(i))

3. Merges the image to a single layer (required for saving)

merged = pdb.gimp_image_merge_visible_layers(im, 0)

4. Saves the image to a specific location.

pdb.file_png_save_defaults(im, merged, full_output_filename, full_output_filename)

To make your script visible (and runnable) by Gimp you need to register it. The second half of the script is the script registration. First line contains the function name, followed by 5 does-not-really-matter parameters.

"chobo_icon_gen", "", "", "", "", "",

Next line, is menu path to your script. The underscore here is a shortcut key (Useful, if you hate using a mouse).

"/Xtns/Languages/Python-Fu/KillerScripts/_Icon Generator", "",

Next is a list of input arguments, which is self-explanatory. I tool me a while to find all available parameter types (You can find them here).

    [
    (PF_FILE, "arg0", "Template file", ""),
    (PF_INT,    "arg1", "Maximum number of icons to create", 29),
    (PF_STRING, "arg3", "Output file prefix", ""),
    (PF_STRING, "arg4", "Output directory (relative to user's home)", ""),
    ],

The last argument is out actual Python function to be called.

Advices

Start small

When writing a script, first start with small steps: create a really dumb script (put a single print ‘Working’), and see if it is working. I killed a lot of time, tracing typos in my Python code. Then I started all over again using sample from Python Scripting in GIMP documentation.

Use console

Python console in GIMP is a really nice feature, that greatly helps writing Python scripts. You can find it at menu Filters -> Python-Fu -> Console. I was really struggling to find a decent documentation of Gimp Scripting API, until I found a Python Procedure Browser, that solved my problems.

You can find the browser by clicking “Browse…” on Python console (Not really intuitive, I would say). You can ask “but how can I actually call these functions in my Python code?”. Just double click on a method, that you’d like to use, and it will appear in console. And you will see that all the functions are located in pdb namespace (of course, all those ugly minuses (“-“) were replaced with underscores (“_”)).

I recommend the following process for writing a script.

  1. Play with functions in Gimp’s Python console.
  2. Change one line in the script
  3. Run the script in batch mode.
  4. Go back to the console
  5. Continue until you’re done

GitHub

I shared the script and the icon template on GitHub here. Feel free to play with it. I hope it’ll be useful.

References:

Posted on December 17, 2010, in programming, python and tagged , , . Bookmark the permalink. 5 Comments.

  1. Nice intro… Just the right amount of instruction to get started… Thanks!

  2. Hello, I am interested in scripting gimp so I try your code. What I have done is described here: http://pastebin.com/i18wgLe8 but nothing happened, I also trying to change from “chobo_icon_gen” to “chobo_icon_gen2” to see if I get some error about undefined function, but I get the same message: “GNU Image Manipulation Program version 2.6.12” and it all ends viwth return code 0. Many thanks

  3. Hello, its good piece of writing concerning media
    print, we all be aware of media is a wonderful source of data.

  4. Nice intro!
    Just one comment, in my case (Mac OS X Mavericks, Gimp 2.8) I had to put the folders of my scripts in the “Plug-ins” folder rather than the “Scripts” Folder. Also, as per

    http://gimpbook.com/scripting/notes.html

    Do not forget to make your script executable.

    Thanks for the post!

    @Tryskele

  5. Gimp is great! But sometimes ImageMagik is better solution 😉

Leave a comment