Image manipulation in the browser

While Picnik gradually converts the functionality of desktop image processing software into online tools (in the hope, presumably, of being bought up by one of the big players), Flash has found other, more piecemeal uses in augmenting the image and font functionality of your average browser. Hot on the heels of sIFR, which replaces text with the equivalent image in a font of your choosing, comes swfIR, a pair of of Flash and Javascript chunks which, between them, permit your browser to rotate and resize images, adding shadows and rounded-corner borders, in situ after they’ve been retrieved from the server.

I’ve never been a fan of gratuitous Flash, but I’ve recently agreed to implement a complex page design (using swfIR) to help a client reuse existing content. Portrait images of users need to look “normal” on an index page, but then be rotated to line up with a fake “polaroid” background at around 2.5 degrees on the user profile page. Rather than have the client upload at least two copies of every image, which seemed a bit mean if we could avoid it, swfIR could do the rotation for us.

Apart from an initial problem, swfIR worked very well, the Javascript interface to the Flash proving very easy to use and the resultant image quality fine for our purposes. There’s the standard background problem with freeware Flash plugins (the background of the bounding box of the plugin’s influence on the page cannot be transparent, and thus chips away at the background polaroid blank on Ubuntu/Firefox) but otherwise it integrated seamlessly into both the design of the site and the technology of our existing Javascript workflow. It also coexisted happily in the browser with the jQuery and MochiKit frameworks, as we’d already restricted the latter’s scope to just the window.MochiKit object: compare this with the declarations on the swfIR site that neither MooTools nor Prototype sit well with their system.

The initial problem I mention above was one of URL paths. The path to the .swf half of the swfIR pair is hard-coded into the object returned by the window.swfir() function. Not only that, but it’s a relative path: just "swfir.swf". When the visitor was viewing the page .../node/100, the Javascript was creating a Flash embedded object that effectively referenced .../node/100/swfir.swf; but then when the visitor navigated to the aggregated view at .../view/all_users, a completely different file was being referenced by the embed. This situation was hardly helped by many of these apparent directories actually not existing on the server at all, but being phantoms, handled by Drupal and Apache cleverness.

The fix for this was eventually fairly simple, but it did involve hacking the Javascript. In swfir.js I changed the function declaration (line 354) to:

function swfir(path)

I then permitted this path to be brought in at the front of the existing hardwired path (line 364):

this.src = (typeof path == “undefined” ? “” : path) + “swfir.swf”;

I could in principle have just overridden it entirely and dropped the hardwired bit, but decided against it for backwards-compatibility reasons. On reflection, too, the object’s property this.src could probably have been modified post-instantiation, but I have enough JS headaches already, working out what different browsers consider to be “mutability,” to want to add another to the contents of my weary cranium.

That’s it, then: the full fix. I’ll mention the issue to the swfIR people shortly. A more foresighted solution would cause that function to accept a whole object as a parameter, an object whose properties could then be used to override any one of the configuration variables currently hardwired around line 360. But this quick and dirty change worked fine. I just wish I could show off the results, but the site itself is still embargoed. As soon as it appears in the real world then you can guarantee that I’ll point everyone I know at it, as it’s arguably one of the best, completest, tightest websites I’ve done, thanks in no small part to the efforts of my co-workers in design and additional development.

Among all this Flash hysteria, of course, it’s important to remember the wise words of Hugh Winkler (via the otherwise ever-quotable Sean McGrath)

Users have voted with their mice, and they’ve voted for the web experience — exploring the web information space using hyperlinks — as far more important than whizzy UI. Ask eBay. Ask MySpace…. It is good to have super expressive widgets — hear hear. But if you’re not pushing a bunch of hypertext down to my browser, you’re not helping me explore the space.

The lesson, I suppose is to use Flash, but use it sparingly, as a progressive enhancement.