Thursday, February 28, 2008

Earning My (Script-Fu) Blackbelt

I've been really impressed with The Gimp 2.4. It's been a really solid performer and with the short-cut keyz situation worked out, a breeze to use.

Today I had to scale about 20 images down to a height of 240px. I also wanted to experiment with different values of the JPEG quality setting. My first thought was to use ImageMagick, but the super handy convert script doesn't easily allow you scale to a specific height (you need to provide both height and width, or just width).

Then it hit me, why don't I whip up a quick Script-Fu plugin to do what I wanted? That script, combined with adding a short-cut key to it, turned out to be an ideal solution. It wasn't quite as automated as a shell script, but allowed me to visually inspect my changes as I went.

And best of all, It Taught Me To Fish, so now I'm more comfortable with scripting the Gimp.

Here's the script I came up with. Notice, it's not parameterized with respect to how the image is scaled or the JPEG quality. I did that on purpose because I didn't want to bother with prompting while using it.

(define (bs-script-fu-scale-and-save img drawable)
  (let* ((orig-width (car (gimp-image-width img)))
         (orig-height (car (gimp-image-height img)))
         (dest-height 240)
         (dest-width (/ (* dest-height orig-width) orig-height)))
    (gimp-drawable-transform-scale-default drawable 0 0 
                                           dest-width dest-height
                                           TRUE TRANSFORM-RESIZE-CROP)
    (gimp-image-resize-to-layers img)
    (file-jpeg-save 1 img drawable 
                    (car (gimp-image-get-filename img))
                    (car (gimp-image-get-filename img))
                    1 0 0 0
                    "Saved by Ben's scale-and-save filter"
                    0 1 0 1)
    (gimp-image-clean-all img)))

 "Scale and Save"
 "Scale an image down and then save it as a reduced jpg"
 "Ben Simon"
 "copyright 2008, Ideas2Executables"
 "Feburary 28, 2008"
 SF-IMAGE      "Image to Scale" 0
 SF-DRAWABLE   "Drawable to Scale" 0
(script-fu-menu-register "bs-script-fu-scale-and-save" "/Filters/Util")

I'm quite impressed with The Gimp's scripting capabilities. Yeah, it's Scheme, which is fun. But it's also highly dynamic, easy to find and read about existing functions, and provides an interactive console where you can try out expressions.

I found these docs here, here, here and here to be helpful in getting comfortable with Script-Fu.

To me, The Gimp wins big points for being so easily scriptable from a developer's perspective. Not so much for fancy effects, but because it allows me to apply my inner programmer to image problems easily.


  1. Anonymous6:01 AM

    To be honest I think a more "mainstream" language such as python or ruby, instead of scheme would be better. But more importantly I think could be that GIMP exposes all its APIs (that can be used for image creation and manipulation) for a user without requiring to suit to a specific language.

    So either people could use the language they want to, or they use a gimp-internal, human readable DSL.

    I just personally am a bit reluctant to dive into scheme, because I already know I will not need scheme outside of Gimp. (One advantage of a gimp-internal language could be that it is very human readable and makes more sense than playing with () parens and '''

  2. Anonymous6:44 AM

    I am always amused by these so-called programmers to refuse to learn Scheme because they "won't be needing it" or because of the ()s, as if you take out all of them you suddenly get Python.


  3. Anonymous7:11 AM

    I used to "know" that I will not need Scheme or other Lisps. It's hard to describe how much I regret it now... I think I could be 10x better programmer by now if I didn't dismiss these languages due to these widely known but very superficial "problems".

  4. Anonymous7:26 AM

    Gimp has Python scripting as well. Not that there's anything inherently wrong with Scheme as an extension language, but I think the particular Scheme bundled with the Gimp is a bit... crude.

  5. Dude.

    convert -geometry 240x99999 or something would do it... the -geometry switch specifies a bounding box, not the actual output size.

  6. whoops, the other way round, 999999x240. something like that anyway.

  7. To convert to a certain height, just do convert -resize x480 photo.jpg photo_resized.jpg Just drop the width before the x and convert will automagically do the right thing.

    Of course, learning to script in Scheme is awesome too, so it's not a bad thing you didn't find that feature :)

  8. Thanks for the tips about convert - I read the docs, and didn't pick up on the suggestions that have been made. Nice.

    Ahhh, the old Scheme is esoteric debate. I think it's probably a simple enough language, that you could probably learn everything you need to know to script in the gimp in a Weekend. If not an afternoon.

    Before you write it off as a bad decision, I'd give it a try. In the amount of time it would take to explain what protected access is in Java, you'd probably be able to explain the entire language.

  9. Anonymous11:48 AM

    Scheme, as it turns out, is a trivial language to learn. There are only 2 things in the whole language--lambda expressions and s-expressions. Once you understand that the operator comes first, and what a lambda is, then everything else is derived from that (letrec, define, named let, cond, etc). Trivial at worst. I learned scheme a few weeks ago. It took about 20 minutes, have never seen a lispy language before. It's such a beautiful, simple, and obvious way to do things!

  10. I should also mention, while Scheme is easy to learn, it's impossible to write without the right tools.

    You absolutely need an editor that will help you forget about parens.

    With the wrong editor, Scheme would be nearly impossible to program. With the right editor, it's a joy.

    If you find the syntax of Scheme getting in the way, then you're using the wrong tools.

  11. "think the particular Scheme bundled with the Gimp is a bit... crude."

    Have you looked into this lately? The scheme implementation was swapped out a while back from SIOD to TinyScheme. TinyScheme is a fairly modern flavor of Scheme that tries to be R5RS friendly.

    May be worth another look.

  12. Anonymous11:58 PM

    I was a big fan of the Emacs-Lisp, being quite proud of showing off with my Lisp programs that only geeks - like me - were able to apprehend in order to customize Emacs.

    For some reasons Lisp and Emacs fit really well together.

    But an image processor like Gimp - that still doesn't offer macros recording - should have a more intuitive language. Lisp is wonderful is some ways, but the mind-work required to, first, write programs and algebraic operations in Lisp... then the again time and nerve consuming work to decode others programs...

    This pops up the question: is Gimp intended to be used by everybody?

    For me, as it is, Gimp is a living advertisement for Photoshop.

  13. Re: Gimp as an ad for Photoshop.

    There's no doubt, that Gimp isn't nearly as polished as Photoshop. And having a scheme scripting capability doesn't help it one tiny bit in that department.

    But, I've found that for the kind of work I do, I can definitely get by with Gimp. And not only that, but using it's flexibility (say in keybindings or scripting in scheme), I can even thrive there.

    I believe Photoshop is scriptable via JavaScript (or a flavor of it). JavaScript and Scheme have the same roots, so my guess is that scripting one vs the other isn't that terribly difficult. Now, if you're more comfortable with Scheme or JavaScript idioms, then yeah, one is going to be a lot more appealing than the other. But, that's just a matter of taste at some point.