Curved corner images in rmagick
RMagick is a great ruby library for image manipulation - it’s basically a wrapper around the venerable ImageMagick libraries. There are some complexities around installing it on some platforms, and you have to be careful with garbage collection, but it’s still very easy to use and very powerful.
The curved corner images I used in previous blog posts could be built in photoshop or gimp or other gui applications, but I wanted something scriptable, so I’m trying to build all images in RMagick - and it’s really not that difficult.
RMagick has a whole set of vector graphics functions, but I’m mainly using one, the roundrectangle function - it’s pretty simple:
image = Magick::Image.new(width+bordsize, height+bordsize) { self.background_color = 'transparent'}
gc = Magick::Draw.new
gc.stroke(bordercolour)
gc.stroke_linecap('round')
gc.stroke_width(bordsize)
gc.fill(innercolour)
gc.roundrectangle(bordsize/2,bordsize/2, width,height, radius, radius)
gc.draw(image)
This basically draws a round rectangle, with a solid border, at offset (bordsize/2,bordsize/2) - you need the offset as otherwise the border edge will overlap the edge of the image.
Adding a shadow is pretty simple, rmagick has the shadow method:
shadow = image.shadow()
image = shadow.composite(image,Magick::NorthWestGravity, Magick::OverCompositeOp)
- this basically works, but sadly you get issues when you save the image. The shadow() method creates a shadow of a given image, with a specified shadow radius, which results in a larger image than the original - so the code above gives you an image which has shadow pixels at negative x and y coordinates! Some file formats cope with this just fine - png files seem to do ok - but I wanted gif images for ie6 fallback, and gif doesn’t cope at all.
Anyway, to cut a long post short, the final code (see below) has a fair bit of logic for allocating extra space in the image for the shadow. An example of the basic image-with-border-and-shadow image:

One last tweak I did - I wanted to have a shadow on the borders - the dark border is nice for some effects, but I wanted a slightly more 3d look:

And a more subtle effect with the raised border the same colour as the diagram:

I also added some logic to set transparency of the image, for pretty backgrounds like the example from my last blog post (sample page here) - and to automatically save a gif version for ie6 display.
The full code can be seen at http://www.sietsma.com/korny/corner_test/corners_code.html
Obviously there’s lots of other things you can do - but this is a useful start!