Posted by Jake Gundersen at iDevBlogADay
When I first began contracting I stumbled on to a tool that I now use all the time, Image Magick. Image Magick is a C library that can be used in all kinds of ways, including inside your iOS app if you want. But, I use it as a command line tool to manipulate image assets.
While there are lots of alternatives, most of which have a more friendly GUI interface, nothing beats the flexibility of the command line. If you aren’t friends with the command line, don’t worry, I’m not either. But, what you can do with Image Magick makes it worth it.
A quick example. You have 1024×1024 pixel icon file, and you want to output all the icon sizes for a universal app. You could do it with the following command line script (your original file is called ‘bigIcon.png’ and is in the same directory):
mkdir output cp bigIcon.png output/iTunesArtwork@2x convert bigIcon.png -resize 57x57 output/Icon.png convert bigIcon.png -resize 114x114 output/Icon@2x.png convert bigIcon.png -resize 72x72 output/Icon-72.png convert bigIcon.png -resize 29x29 output/Icon-Small.png convert bigIcon.png -resize 50x50 output/Icon-Small-50.png convert bigIcon.png -resize 58x58 output/Icon-Small@2x.png convert bigIcon.png -resize 50% output/iTunesArtwork
The first two lines create and output directory and then copy the bigIcon.png file into that directory renaming it to ‘iTunesArtwork@2x’. All the subsequent lines use ImageMagick’s convert tool to resize them to a specific size and put the output file, named appropriately, into the output folder. Take a look at that last line, instead of supplying a size, you can supply a ratio, in percent format, and it will do the math (1024×1025 * .5 = 512×512) for you.
You could supply two percentages, one for each dimension ‘-resize 50%x40%’. You can give it instructions on retaining aspect ratios. There are lots more options with the resize tool.
This script can be put into a shell script, or copy and pasted onto the command line, and it will be done before you can even finish loading photoshop.
Speed is nice, but that’s not really the point. The real boon is the flexibility. What if your designer send you a series of images in .psd format and you need them all in .png format? What if you need the name of the output .png to be named the same as the layer name? What if you need it to create a retina and non retina set of those images? You can do all that with ImageMagick.
You can also perform all manner of image processing using the convert tool. You can blur images with a gaussian blur, you can do color alterations, you can crop or enlarge canvas of images, you can combine multiple images into a collage, you can blend images, there aren’t many things you can’t do with it.
Check out the convert command line tool page for a list of options and their usage here. Also, Fred Weinhaus has put together a huge set of scripts using Image Magick to do more advanced image processing (things like edge detection, pixellization, cartoon filter, etc).
Installing Image Magick
There are lots of ways to install Image Magick, my personal favorite is to use Homebrew. It seems to me to be the easiest and cleanest. You can find out how to install Homebrew here. Once you have Homebrew installed, installing Image Magick is easy:
brew install imagemagick
If that gives you trouble, here’s a thread on SO talking about it.
There are lots of other ways to install Image Magick, the most direct is to just download the binary and put it in a directory (anywhere). In that case you’ll need to set a handful of environment variables to use it. I used to do it this way, but brew is easier (and has always worked for me).
A couple more scripts
Earlier I mentioned that you could convert psd files to png files and even inspect the psd file to get the layer names. Here are a couple of examples of that. First, just convert all the psd files in a directory to png files (and put them in an ‘output’ folder):
for f in *.psd do myStem=`echo $f | sed 's/.psd//'` convert $f output/$myStem.png done
The first line starts a for loop, iterating once for each .psd file in the current directory. For and do are how the loop is constructed. The variable ‘f’ now contains the name of the psd file that the current loop iteration is working on. To access ‘f’ you must use ‘$f’.
The second line sets the variable ‘myStem’ to the file name without the .psd extension. ‘echo $f’ outputs the file name, the ‘|’ operator pushes that file name to the ‘sed ‘s/.psd//’ command, which does a search and replace (search for .psd, replace it with nothing).
Finally, the convert line uses the $f (the whole filename) with a  behind it. I’ll explain what  does in just a second. The last part of the line output/$myStem.png creates a filename in the output directory with a file extension of .png and the name of the original .psd file. ImageMagick knows from the extension which file format to create.
In Image Magick if you are dealing with .psd files and layers,  is the root and represents all the layers. If you put  you’d get the first layer. If you use convert on a .psd file without [x] it will iterate through all the layers, giving you a numbered file output for each layer, and an additional one for all the layers. It will automatically crop all these layers to their pixel bounds.
You can also rewrite this so it’s one line, like this:
for f in *.psd; do stem=`echo $f | sed 's/.psd//'`;convert $f output/$stem.png; done
Finally, I promised that you could output those .psd layers, using the names of the layers as filenames. Here’s what that would look like:
num=`convert test.psd -format "%[scenes]" info: | head -n 1` for ((i=1;i<$num;i++)) do myStem=`convert test.psd[$i] -verbose info: | grep "label:" | cut -d: -f 2 | cut -d: -f 2` convert test.psd[$i] $myStem.png done
The first line gets the number of layers in the psd file (called ‘test.psd’). I can’t take credit for this script, nor can I completely explain it, because I got it from the Image Magick forums. The good news is, you can do the same thing, google what you need to do with Image Magick and you can usually find a script that will help you.
As I said earlier, I’m not really a command line guy. Beauty is, you don’t need to be
The ‘-format “%[scenes]” info:’ command retrieves the metadata and the ‘| head -n 1? piece reduces it to a single value (try it without the last chunk and see what you get). This places the number of layers, including the  layer (which is the root, not an actual distinct layer) into the num variable.
Next the for line constructs a loop which starts at 1 (instead of 0) and goes to num-1 (index of the last number, indexes are one less than the number, starting at 0). This way you skip the root and only convert the individual layers. ‘$i’ will now contain the index of the current layer.
The next line gets the layer name. ‘Convert test.psd[$i] -verbose info:’ extracts a bunch of metadata from the .psd file. Then that is piped into the grep command which will search the whole thing and retrieve the ‘label:’ string. The last two pipes just cut off any extra, unnecessary characters, leaving you with the name of that layer. It’s held in the myStem variable.
Finally, the convert command is invoked on the current layer, using the $myStem variable to name the output file.
If you are put off by the bash scripting, don’t be. You don’t have to be a master to get good use out of it. Here’s just a few quick things. The weird single quote, ‘`’ character (below the tilde) is necessary when you are putting the result of a command into a variable. The ‘|’ character takes the result of one command and ‘pipes’ it into another. You can create loops with for . . . do . . . done. Set a variable by typing it’s name, but access it with the ‘$’ character in front of it.
If you can remember those things, you should be able to google the rest, like specific command functions (cut, grep, sed, etc).
I’ve only barely scratched the surface of what Image Magick can do. If you have other uses for mobile developers, put em in the comments!