Javascript and ImageMagick sitting in a tree…

I’m really excited about an upcoming feature in Pixenate. Pixenate is extensible, that is, if there isn’t a tool that pixenate already does, you can add it yourself by writing a Pixenate plugin. Want to know what a Pixenate plugin is? Simple. It’s a piece of code which operates on the photo. Here’s the Enhance plugin…

use strict;
use Sxoop::PXN8 ':all';
sub enhance
  my ($image) = @_;
  return $image;
AddOperation('enhance', \&enhance);

Pretty simple huh? Once you know a little Perl and a little ImageMagick, writing Pixenate plugins is a breeze. This feature has been present since day one and many of our customers have written their own plugins.
I was thinking for a long time that it would be nice to be able to write plugins in Javascript since – you know – that’s what many Pixenate developers dabble in anyway. Well [drum roll] … now you can…

function enhance(){
   var image = PXN8.ImageMagick.start();

Pretty neat huh? There’s a more detailed discussion of this in the Pixenate API Reference. Basically what we’ve done is exposed all of the Image Manipulation methods available in ImageMagick (sorry no Write() method – allowing client code call this directly would be amazingly stupid). We’re still testing this out but we hope to release it in the next update of Pixenate which should be due in the next few days.
What’s interesting about PXN8.ImageMagick is that it is a Mock Object. When you invoke …


… in javascript, nothing happens to the image, in fact nothing happens until you invoke …


… All calls to Method simply store the method name and object id in an internal array. That array (of object ids and methods) is eventually submitted to the server when the PXN8.ImageMagick.end() function is invoked.
I began working on this a couple of days ago. Initially there was no API, just JSON. I had to think carefully about the data representation in JSON first – how do I represent something like the following perl code in JSON?

my $shadow = new Image::Magick();
$shadow->Set(size => "500x333");
$image->Composite(image => $shadow, compose=>"Over");

There’s a lot going on in the above code, new objects being created, methods being called, and parameters being passed . To complicate things further, some of those parameters are themselves objects. The solution I came up with was this…

 [ "shadow", "Set", {size: "500x333"} ],
 [ "shadow", "Read", "xc:black" ],
 [ "image", "Composite", {image: {handle: "shadow"}, compose: "Over"}]

As you can see it’s an array where every element is a statement. Each statement is itself an array consisting of 3 elements, an object id, method name, and (optional) parameters.
A couple of points of interest…

  • If a symbol (e.g. “shadow”) doesn’t already exist then a new Image::Magick object is created and assigned to that symbol/variable.
  • I used the {handle: “symbolName”} notation to indicate parameters which where themselves Image::Magick objects (see for example the Composite method).

Once I’d settled on a JSON (data) representation, wrapping a procedural interface (api) around it was a no-brainer. JSON is good but …

var shadow = new PXN8.ImageMagick();
shadow.Method("Set",{size: "500x333"});
image.Method("Composite",{image: shadow, compose: "Over"});

… is just so much easier to read and maintain, and it maps pretty well to what the Perl code would have looked like on the server (had it been implemented as a pure server-side plugin).

A couple of caveats: Right now, the javascript API doesn’t support ImageMagick’s Get method so you’ll still need to write Perl code if you want to do some complex stuff. However, it’s surprising just how much you can do with the Javascript API, you can see a demonstration which creates a polaroid photo effect here.
The code is still in early stages so I need to do more testing before (if?) I roll this into the next release.
The really neat thing is that the client-side PXN8.ImageMagick code is really small (most of that source file is a comment which gets rolled into the API reference document using Markdown – the subject of another post in waiting). Everything just fell out from the JSON representation – nailing down what your data looks like on the wire really pays off when you start writing a procedural interface.
Right now I’m giddy at the idea of being able to create new Pixenate plugins in Javascript. The more I play with Javascript, the more I’m convinced it is (as Steve Yegge calls it) the Next big language. It’s just so elegant, expressive and flexible – so unlike Java.

Tagged , ,

One thought on “Javascript and ImageMagick sitting in a tree…

  1. […] – bookmarked by 3 members originally found by jrboyd on 2008-11-19 Javascript and ImageMagick sitting in a tree… – bookmarked […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: