Replacing Common Photoshop workflows with ImageMagick
Photoshop is a wonderful tool, but it tends to require mousing (even with shortcuts), likes to eat up as much RAM as possible, and doesn't play nice with bash scripts. Thats why I prefer Image Magick: a quirky, insanely full-featured CLI image manipulation library. I'll run through some examples of using it do a few common tasks that I previously used photoshop for, such as:
- Identify the size/type of image
- Convert image types
- Resize images to a maximum width/height
- Reduce image filesize
- Trim Whitespace
- Create new images from scratch
- Add borders
Example Repository
If you want to follow along, i've created an example repository with some source files. I'll be referencing them through the post.
Installation
Mac Os X
Mac users can (and should) use brew :
brew install imagemagick
Linux
Most linux distributions should have the imagemagick
package available by default.
For Ubuntu:
apt-get install imagemagick
There be dragons: Mogrify Vs. Convert
One important thing to cover before we start slicing and dicing images is that IM has two major methods for manipulating images: convert
and mogrify
. Convert
takes a source file, makes whatever changes you desire to it and ouptus them to a file you specify. Mogrify
only accepts one file, and makes all changes on that file (unless you specify a destination directory). mogrify
has a simpler syntax for performing batch operations on images, but that elegance comes with the potential of deleting precious content. There's an example of how to handle batch operations using both commands in the "resize" section later on. For now, just be warned that mogrify
will write any changes you make to the original files. Back up early; back up often.
Identify the size and type of images
identify
is great for getting a quick overview of an image's properties.
Our example's source file includes an image file named 300
, which i've nabbed from PlaceKitten. Photoshop doesn't know what to do with the image, because it is missing an extension, and while we could try and guess the extension by renaming the file to (gif|png|jpg) and seeing what happens, but it's cooler (and faster) to use the identify
command to figure things out:
identify 300
300 JPEG 200x200 200x200+0+0 8-bit sRGB 8KB 0.000u 0:00.009
Ah, a jpeg. I suspected it all along.
Formatting identify's output
The default output of the identify
command is a little verbose for my taste. We can trim it down by using IM built in -format
escapes
# Print the name, and dimensions of the file named 300
identify -format "Name: %f Dimensions: %P Type: %m" 300
Batch identification is simple with your shell's built in globbing:
# '*' will get you more than you ask for, so it's best to narrow
# things down based on the file structure you are dealing with
identify *
Convert image formats
Imagemagick's powerhouse is the convert
command. You can use it to do almost anything you can imagine through some terrifyingly complex flags. We'll try to keep things simple : )
Convert from tiff
to jpg
Image magick can effortlessly convert images between various formats. A problem one of my coworkers ran into recently involved clients needing images in the tiff
format. Photoshop can do batch operations, but the process is clunky, and — in my experience— unreliable.
Single Images:
convert convert.tiff kitten.jpg
Simple, no?
Multiple Images:
- destroying the original image:
mogrify
mogrify --format tiff *.jpg
- retaining the original image, the
mogrify
command can be used with the-path
flagmogrify --format tiff -path converted *.jpg
- The path (in this case the 'converted' directory) must exist, or IM will complain
- Make sure that this path is different than the files you are using
mogrify
on, or they will be overwritten.
- retaining the original image, you can use a long
convert
statement (see batch resizing below).
Resize images
Simple Resize
convert kitten.jpg -resize 80% resized-kitten.jpg
Batch Resizing
Clients rarely have a images in a uniform, web-optimized format, and even if they do I usually need need two copies: retina-ready images, and images for us normal folks. ImageMagick makes generating those a snap.
In our resize/batch
folder:
convert *.jpg -resize 80% -set filename:f '%t@2x' '%[filename:f].jpg'
Here we are resizing all jpg images by 80%, setting the filename the filename %t
plus the string @2x
to follow apple's convention for retina images, and then outputting the file. The syntax is a little esoteric (more details on that here), but once you get the hang of it it can be quite useful.
We can now run mogrify !(*@2x).jpg -resize 40%
to cut the non retina images down to size (note, this will "destroy" the original images -- I have a backup handy).
Resizing to a maximum pixel width
If you have do not have a specific size for your images, but want to keep things small, you can use the following syntax:
In our resize
folder, there is a max width image. Running identify gives us the following:
max-width.jpg JPEG 408x287 408x287+0+0 8-bit sRGB 15.8KB 0.000u 0:00.000
Let's resize that to a max width of 200px:
convert max-width.jpg -resize 200\> max-width-resized.jpg
One special thing to note is the icky need for the \
in \>
. This is necessary to escape to prevent your shell from interpreting that as an output redirection >
.
Replacing "save-for-web" and reducing file size with -strip
When resizing images (especially large images), you may notice that the file size of the images does not decrease as much as you might expect. This is typically due the meta-data and other kruft that may come attached to your image file. Using the -strip
flag on any IM operation will remove this data, which, in my experience, typically results in a 10-30% reduction in size.
In our trim
folder:
convert -strip strip.jpg stripped.jpg
Use identify
to compare the file sizes. Not a huge reduction (this image is pretty slim already), but imagine those percentage savings being applied to a larger image.
Obviously, Photoshop's "Save for web" combines resizing and optimizing functions, but you can too.
convert sample.png -strip -resize 80% optimized.png
Borders
Add a 5px black border to an image.
In our borders
folder:
convert kitten.jpg -bordercolor '#000' -border 5 bordered.jpg
Trim Whitespace
My jaw dropped when I first found out about this command (thanks to this brilliant gentleman)
In our trim-whitespace
folder
convert trim.png -trim trimmed.png
Unfortunately, for images with gradients, or subtle transitions between subject/background, the results are not quite as spectacular:
convert not-quite-trim.jpg -trim not-quite-trimmed.jpg
Will output an image that still has a background bleed :(
Create Images from the command line
Imagemagick can also help you with bespoke iamges as well, if you need some filler content and can't use a service like placehold.it or (my favorite) placekitten.com.
To create a simple gray (usinga hex value), sized 100x100 you can use the convert command.
-
Solid Color:
convert -size 100x100 canvas:#a19c9e canvas.png
(note, you may need to quote/escape hex colors, as your shell may try glob them) -
Gradient:
convert -size 100x100 gradient:#a19c9e-#000000 canvas.png
-
Pattern:
convert -size 100x100 pattern:HEXAGONS canvas.png
There are a host of options here
The start of a beautiful friendship
Hopefully these examples have whet your appetite for handling images on the command line. IM can do so so much more, and all those features are listed in IM's extensive documentation.
Notes
Os X Users: sips
If you don't want to bother installing IM, or you are on a friend's Macbook and can't. Use the built-in utility sips
to do some batch image processing. While not as robust as ImageMagick, it suffice in a pinch. More on that here.
IM and Build Processes
While IM is an excellent choice for performing large batch operations on images, it has been my experience that it is better suited for one off batch jobs than a constant build/deploy process. I'd suggest using tools like the HTML5 BoilerPlate Build script or Grunt with the grunt-contrib-imgmin plugin on projects that may need to consistently run and rerun optimization.
A note on Performance
ImageMagick has a more performant fork GraphicsMagick if you are concerned about keeping resource usage down or if you are etsy. Most of the commands are similar, but the differences between the command structure and GM's elusive api documentation make starting with imageMagick a better fit. You can always move on to GM when performance becomes a concern.
Corrections
If you are a command-line master, and i've missed something or missed a performant shortcut, don't hesitate to note it in the comments. Or open an issue