ImageMagick: One-Second Gradient Images

Command-Line, CSS, Design, Gradient, HTML, ImageMagick, Tutorial, Web2.0

Problem: The great thing about standards-based web development is how easily you can tweak the look by modifying CSS properties. However, contemporary gimmicksconstructs like curved surfaces and gradients aren’t yet supported, which means simple tweaks – like changing a colour – usually require a round-trip between a graphical editor (Photoshop, Gimp, etc) and your CSS file. Or, you might be able to just make the change in your editor, but even that will take a lot longer than editing the CSS file, anywhere between 10 and 100 times as long (usually 1-5 minutes versus 1-5 seconds).

Solution: Generate images on the command line. Using ImageMagick, it’s possible to do tons of things on the command line. ImageMagick, which usually is executed with the “convert” command, is probably installed on your Unix/OSX machine already and your Linux web host as well (many Captcha utilities use ImageMagick to create and warp the image). It’s extremely powerful. Until today, I’d only ever used it for transformations, but now I’m using it for image generation too. Unfortunately, it’s not too well documented – the official docs are thorough, but completely lack examples (a common problem with open-source projects is documents oriented around the features rather than the typical tasks, and often in the absence of any useful examples that in this case would show how to construct a command-line). Fortunately, there’s this set of examples.

You can generate (and therefore easily tweak) logos, curved surfaces, etc, but what I’ll talk about here is gradient images. If you want, jump straight to the one-line examples below. The trick relies on several features of ImageMagick, pseudo-images, image stacks, and appending:

  • ImageMagick usually works by converting one image to another, e.g. “convert -transparent white normal.gif transparent.gif”. But we want to create an image from nowhere, so what ImageMagick lets us do is create an input image from thin air, a “pseudo-image”. To create a pure red image, we use a pseudo-image of type Canvas, mysteriously named “xc”. Go on, type this in right now to make a pure red GIF image:
    convert -size 3000x120 xc:red /tmp/red.gif

    Canvas is only one example of a pseudo-image; there are pseudo-images based on patterns, fractal generation, etc. (In fact, there is a pseudo-image called “rose:” which is actually a photo of a rose that ships with ImageMagick, a brilliant feature as it means people can write tutorials that manipulate the image without requiring you to download it.) We can generate a gradient image using a gradient pseudo-image.

  • Optionally, it’s useful to work with an “image stack” – sometimes you need more than one transformation to get to your desired image. Instead of dumping all those intermediate images in temp files along the way, ImageMagick offers a nice, clean way to build a transient image. It’s like saying “final=a+(b-c)” instead of “temp=b-c; final=a+temp” (the Replace Temp with Query refactoring :-)). A transient image is created with parentheses (example below).
  • Images can be combined together: convert a.gif b.gif -append c.gif will stack a on b vertically to output c. (+append will stack horizontally).

So how to generate a gradient image?

Simplest technique is:

convert -size 2000x100 gradient:#4b4-#bfb /tmp/greenbar.gif

Great! Now we can tweak the colour without going through all the hassle of mousing around a graphics utility.

Say we want that bar to be the top of a box, where the rest of the box is the same colour as the bottom of the gradient bar (so the bar blends directly into it). One way is to keep the gradient image as is, and alter the CSS background-color, so we have a CSS line like:

gradientBox { background-image: url(greenbar.gif); background-repeat: no-repeat; background-color:#bfb; }

That’s neat, but does require two updates each time you want to change the colour (one to the imagemagick command-line and one to the CSS). You could also generate a gradient leading to colour “none”, which means it’s transparent – still have to update the CSS to update the other colour but there’s no redundancy. Another way is to build a big image (at least during development). We can do that by stacking a single-colour image under the gradient image, using the transient image and appending techniques described above (the parentheses are escaped with \ for the Unix command line):

convert (gradient:#995-#cc9 -size 3000x120) -append (xc:#c9 -size 3000x1000) /tmp/greenbox.gif

BTW One thing about these gradient images is that GIF format (and PNG too I think) strangely doesn’t compress them at all well – increase the width from 1 pixel to 100 pixels and the file size will also increase by a factor of 20 to 50. It’s surprising as the information content is virtually identical, but the consequence anyway is that you should generally use just a single pixel wide and CSS style background-repeat: repeat-x to stretch it out.

Now you can update your bling with the touch a key!

8 thoughts on ImageMagick: One-Second Gradient Images

  1. Pingback: CyanCode » Blog Archive » Code Links (11.29.2006)

  2. Thanks for the piece. It’s quite timely since I just needed to do just this today. Problem is, I wanted to do a PNG mask, with alpha transparency, so I can overlay the image on top of any CSS-set color. Only, I can’t make that aspect work. It should work to do something like convert -size 10×32 -gradient:#FFF0-#FFFF, where the last character of each color is the alpha transparency. But, no. It doesn’t work. All I get is solid white (or black).

    I’ll probably poke on it some more tonight, with a newer version of IM (my Debian Sarge box is running version 6.0.6, I’ve got Etch running at home).

    Again, thanks for the article…

    Michael

  3. Michael, I had a similar issue. I tried using “none” and “transparent” as the colour args as they are keywords in IM, but didn’t work.

    In my case, it wasn’t involving gradient, so I could just do it in two stages – generate an arbitrary colour (e.g. “pink”), then make that colour transparent (“-transparent pink”). Not sure how to solve your problem :?

  4. Well, I was able to make it work on the Windows version… sort of. If I try to put the black first, it’s all black, no transparency. With white first, it’s all white, but the transparency varies. That kinda works for what I want. Eventually we’ll have an artist do everything, so the kinda works will work for now ;)

    Thanks again for the article.

    BTW, I’m working through Ajax Design Patterns… very good. I’m glad I got it :)

  5. Does that mean ImageMagick is not good for beginners who knows nothing at all about computers, programming, etc…

    I’m learning html to build my website and now I come to the point to put graphics for my site. The reason I want to use imagemagick.

    I am no techie, just have a passion to learn with patience.

    What can you recommend for me, ImageMagick or GIMP?

    Thanks for your help.

    Maria

  6. hi i am new to ruby, i have developed an simple application in ror by image upload functionality, in order to display the image i want to resize the image to thumbnail size, how can i do it, i have to use Rmagic or imagemagic ?

  7. Pingback: Photoshop Tamagotchi

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>