Mobile toolbar icons – sprite generation with Imagemagick

Geek Alert ! Geek Alert ! Geek Alert ! Geek Alert !

OK, all normal people have been warned. This is what happens when you mate graphic design with UI development.

actions_60Toolbars are a pretty common user interface mechanism. A series of graphical icons – each representing some action – are displayed side by side by side. Clicking or tapping on one, will initiate its specific action. Ideally, it will change color or shape or give some other indication that it has been effected.

Let’s assume we have four actions. That equates to four graphical icons. We also need alternate versions which indicate one has been effected. So we have eight images. For performance reasons, we really want to have just one image that is the combination of all eight images. This is called a sprite or sprite sheet. (Many of the web applications frameworks even assume the images have been combined.)

It’s not overly difficult to take a bunch of graphical icons, duplicate them and color or shade the duplicates, and then position them side by side by side and finally save the result as a single image.

It’s 8*4+1 steps (assuming our 4 icons). But wait. The graphic designer just changed one of the graphics. No worries, it’s just another 8*4+1 steps. Oops. There was a problem with one of the graphics. OK. Another 8*4+1 steps. Hey, can we change the coloration a bit ? Ugh. Another 8*4+1 steps. Umm … the new color still isn’t quite right. #%^%%&^&% 8*4+1 steps ! OK, the boss just asked us to add an icon. GET OUT OF MY OFFICE OR I WILL … #$^&$%#%

Calmer heads prevail and we reach for ImageMagick.

Lets’ break things down into a few steps.

  1. the graphic designer was working with black icons but since our toolbar will have a gradient grey/black background, we need light grey icons
  2. we want each icon to have an orange hint to it when it is selected
  3. we want to combine the icons into two rows with the light grey on top and the orange on the bottom. Finally, we want two different sizes for the output
    • one set will have all of the icons 40×40
    • one set will have all of the icons 20×20


we use the ImageMagick "convert" command to process each icon …

convert iconX.png -negate -modulate 85 tmp\normal_iconX.png

This command inverts the black icon to white and then make it 85% of its original brightness.

Now we process each icon again …

convert iconX.png -negate -modulate 65 -fill "#ff7f00" -tint 100 tmp\selected_iconX.png

Again we invert the black icon and lower its brightness a bit before tinting it with our color. The trick here is to pick the color first and then adjust the modulation to affect its brightness.

Finally we use the ImageMagick "montage" command to create the sprite …

montage -background transparent -tile 4×2 -geometry 20×20+2+2 tmp/*.png sprite20.png
montage -background transparent -tile 4×2 -geometry 40×40+2+2 tmp/*.png sprite40.png

Here we are combining all of the images. We specify we want the output to be 4 icons across in two rows. We also scale the individual images to 20×20 or 40×40 and we add 2 pixels of padding (the padding is not absolutely required but makes the resulting sprite easier to view.)

In production, all of this is done is a script file so the process of each icon is done in a loop and the montage can account for how many icons are in each row as well as control the order. … but you get the idea.

Oh, one more thing. Sprites are useful even if you are not using a JavaScript framework. You can reference any graphic in a sprite using CSS …

/* increment by 44 pixels = each icon is 40×40 and has 2 pixels of padding on all sides */
background: url(sprite40.png’) -44px 0;} // second image, first row
background: url(sprite40.png’) -88px -44px;} // third image, second row

Keep telling your boss that each change takes 8*4+1 steps. That way, you can say you’ll finish the new update in 30 minutes – click a button, have it done in 30 seconds, and go get a coffee !

Comments are closed.