Oct 25, 2009

Running GIMP Python plugins in batch mode

In the previous entry I wrote about creating GIMP plugins in Python. This follows up on that by showing the bit of magic for running one of these plugins in batch mode from the command line. You need to provide values for each positional parameter defined for the plugin. It helps if the plugin has been designed with batch mode in mind.
gimp -ib '(python-fu-mylogo-batch RUN-NONINTERACTIVE "in.jpg" "out.jpg" "Made by me" 50 "Sans" 24)(gimp-quit 1)'
The language used is TinyScheme, I don't know how to use Python in this mode, but it matters very little. Any function defined in the PDB can be called including of course Python functions. Add --verbose to the command line to see the execution flow. As a side note, you can use the following command to start the PDB browser directly without going through the GIMP UI:
gimp -ib '(plug-in-dbbrowser RUN-INTERACTIVE)(gimp-quit 1)'

To make a batch mode function, add a function that opens the image, calls the main plugin function and then saves the result. Register this function also, probably under "<Image>/Tools" this time.
def mylogo_batch(infile, outfile, text, opacity, fontname, fontsize):
img = pdb.gimp_file_load(infile, infile)
pdb.python_fu_mylogo(img, text, opacity, fontname, fontsize)
pdb.gimp_image_flatten(img)
drawable = pdb.gimp_image_get_active_layer(img)
pdb.gimp_file_save(img, drawable, outfile, outfile)
pdb.gimp_image_delete(img)

The batch plugin can be invoked from the UI also, a file selection dialog will prompt the user to choose the input and output and so on.

Sep 18, 2009

Writing GIMP 2.6 Python plugins

The GIMP now has Python support in addition to TinyScheme, allowing you to harness the power of GIMP in Python. The following is a simple logo plugin written in Python, usable as a template to write more complex ones. The plugin writes a logo in the bottom-right corner of your image.

#!/usr/bin/python

from gimpfu import *

gettext.install("gimp20-python", gimp.locale_directory, unicode=True)

def mylogo(img, text, opacity, fontname, fontsize):
  gimp.context_push()
  color = (255,255,255)
  pdb.gimp_context_set_foreground(color)
  logo_layer = pdb.gimp_text_fontname(img, None, 0, 0, text, 0, 1,
   fontsize, POINTS, fontname)
  pdb.gimp_layer_set_opacity(logo_layer, opacity)
  x = img.width - logo_layer.width
  y = img.height - logo_layer.height
  pdb.gimp_layer_translate(logo_layer, x, y)
  gimp.context_pop()

register(
  "python-fu-mylogo",
  N_("Add logo to image"),
  "Adds a logo to the bottom-right corner of the image.",
  "", # author name
  "", # copyright owner
  "2009-09-18", # date
  N_("Add logo..."), # text to show in menu
  "RGB*, GRAY*", # image types we can work with
  # Positional parameter definitions, each entry in this format:
  # (TYPE, "name", "caption", default, ...)
  [
    (PF_IMAGE, "image", "Input image", None),
    (PF_STRING, "text", _("Text"), _(u"\xa92009")),
    (PF_SLIDER, "opacity", _("Opacity"), 50, (0,100,1)),
    (PF_FONT, "fontname", _("Font"), "Sans"),
    (PF_INT, "fontsize", _("Size"), 24),
  ],
  # Return values list
  [],
  mylogo, # function name
  # Where to add in menu structure
  # Special tag <Image> indicates you must have an open image
  menu="<Image>/Filters/Render",
  domain=("gimp20-python", gimp.locale_directory)
)
main()

Write ~/.gimp-2.6/plug-ins/mylogo.py and make sure it is executable, or GIMP will ignore it! After restarting GIMP and opening an image file, you will be able to invoke "Add logo..." from the Filters/Render submenu.

All the functions you can use to manipulate an image are in the "Procedural Database", accessible in Python as methods of the pdb object. The list of functions and their documentation can be found using procedure browser: Filters / Python-Fu / Console, click "Browse...". Just remember that the Python names have underscores instead of dashes as illustrated in the code above.

You will also find your own plugins there (search for "mylogo").

References:

May 28, 2009

Fixing yum for older Fedora installations

On an old Fedora system (say Core 5 or 6), you may encounter this problem:

# yum list kernel
Setting up repositories
Error: Cannot find a valid baseurl for repo: core

For releases that have reached EOL (end of life), this happens because their repositories are no longer available on the Fedora Public Active Mirrors system.

They are, however, still available in the archives. The solution is to update the yum repository configuration to use the archives instead of the now nonfunctional mirrorlist.

# cd /etc/yum.repos.d/
# ls
fedora-core.repo fedora-updates.repo fedora-extras.repo

There may be more files there, but those are the ones you need to change. Edit each of the above files and go to the first section, called [core], [updates] and [extras], respectively. You don't need to bother with the other sections, as they have "enabled=0" so they are not normally used. Comment out mirrorlist (and existing baseurl, if not already done) and add a new baseurl line, as shown below (the additions are shown in darker color):

fedora-core.repo
[core]
name=Fedora Core $releasever - $basearch
#baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/$releasever/$basearch/os/
#mirrorlist=http://fedora.redhat.com/download/mirrors/fedora-core-$releasever
baseurl=http://archives.fedoraproject.org/pub/archive/fedora/linux/core/$releasever/$basearch/os

fedora-updates.repo
[updates]
name=Fedora Core $releasever - $basearch - Updates
#baseurl=http://download.fedora.redhat.com/pub/fedora/linux/core/updates/$releasever/$basearch/
#mirrorlist=http://fedora.redhat.com/download/mirrors/updates-released-fc$releasever
baseurl=http://archives.fedoraproject.org/pub/archive/fedora/linux/core/updates/$releasever/$basearch/

fedora-extras.repo
[extras]
name=Fedora Extras $releasever - $basearch
#baseurl=http://download.fedora.redhat.com/pub/fedora/linux/extras/$releasever/$basearch/
#mirrorlist=http://fedora.redhat.com/download/mirrors/fedora-extras-$releasever
baseurl=http://archives.fedoraproject.org/pub/archive/fedora/linux/extras/$releasever/$basearch/


You may need to run "yum clean all" afterwards to remove the old data from the yum cache.