14 March 2012

If you’ve been working on a computer for any amount of time, you may have noticed yourself repeating tasks over and over on a group of files. If you want any chance of becoming a hacker you need to start asking yourself “Isn’t there an easier way?”.

Automation is the process of getting tasks to run themselves. In reality, there are two types of computerized automation: programming is automation that is built around a general scheme and may accomplish more than one task. Scripting is the ordered, linear process of accomplishing a task (usually one particular task).

In both cases, we deal with coding. The simplest definition of coding is putting intructions into a file. For our purposes, we will assume that your machine is running Linux or Mac OSX. Scripting in Windows is vastly different and will warrent its own tutorial. Until then, try installing cygwin and following along.

This is tricky, but don’t panic, I’m going to talk you through this:

  1. Open a terminal. If you’re a linux user, you can usually find a terminal under: Accessories > Terminal Emulator. Mac OS X comes with Darwin, found under Go > Applications > Utilities > Terminal

  2. Don’t panic. Terminals have been around for a while and there are a few tricks to be aware of:

    • You can use the arrow keys to revisit commands entered into the history.
    • The Tab key will try to complete the command or filename if it exists in the directory.
    • The man command will list documentation for a particular command. Usage is like this: man gimp for help on the GIMP. Press q to exit a manpage and space to keep reading. / will initiate a search, enter your term and hit Enter to search for the word.
    • If you don’t know what command you’re looking for apropos will search manpages for similar commands.
    • Google is your friend. If you’re getting stuck and you get an error, try entering it into Google. (Fun fact: linux command pages were some of the first to be indexed by Google).
  3. Use the cd (change directory) command to navigate to your Pictures directory. For example, cd /home/bobby/Pictures/ will go to Bobby’s home picture directory in Linux.

  4. Use the ls command to list all the files in the directory. We will be messing with the file Example.jpg in our examples.

Selecting and Manipulation: Redux

Remember that every command in computing boils down to selection and manipulation. In the steps above, we have successfully selected a bunch of images and now we will manipulate them with imagemagick.

Getting Imagemagick

To convert photos, you will need to install the imagemagick packages. This is trivial in a Linux system, simply use your package manager:

  • Ubuntu/Debian: sudo apt-get install imagemagick
  • Arch Linux: sudo pacman -S imagemagick

Getting imagemagick on Mac OS X is a little more involved and the instructions are beyond the scope of this document. A good starting point is to install MacPorts. Unfortunately, an XCode install will require you to get an Apple ID. If this is a concern for you, you should probably remove Mac OS X from your computers and/or organization. If this isn’t a concern for you, then you should re-read the part in the XCode licensing where Apple basically claims ownership of anything you create in XCode.

Converting the Images

Now that we have our program, we can start on the manipulation phase. Imagemagick comes with two main commands: convert and mogrify. Both essentiall operate in the same way, except that convert will create a new image while mogrify will modify the image in place and overwrite the original. For our example, we will be using convert.

Now what?

So we have our image Example.jpg and we have our command convert. How do we combine the noun (the image) with the verb (the command)? Remember that we can use the man command to explore a command, and that we can use / within the man command to find a particular phrase. So run, man convert and press /. Then type in resize and hit enter.

After reading the man pages we know that if we want to convert this image to 600 pixels in width, we would use the following command:

$ convert -resize 600x Example.jpg Example-600.jpg

and if we wanted to convert this image to 300 pixels in height, we could use the following command:

$ convert -resize x300 Example.jpg Example-600.jpg

All the files

This trick may be helpful for a couple of files in a folder, but what happens when we need to convert all of the files in a folder? Well, first we need to select them all, then we need to manipulate them all.

Selecting All the Files

To list all of the files in a directory, we know now to simply issue the ls command. But did you know that you can also specify which files are listed? If you issue the command ls *.jpg then only files ending in .jpg will be listed (remember that this is case-sensitive, so capitalization matters). The * character is known as a wildcard selector and will select any numbers, letters, or spaces in a filename. Try experimenting with this: Example*.jpg, *mpl*.jpg, and Example.* would all select the Example.jpg file, but the last command would also select an Example.png file. This is why one must take great care in naming things on a computer – you may have to remember these names to make precise selections.

Manipulating the Files

Suppose we have a folder full of files we want to scale to the width of 800px. We know the general command we will be running on each file (note that stuff inside brackets <like this> represent a holding-place for a variable):

$ convert -resize 800x <filename>.jpg <filename>-600.jpg

Selecting files one-by-one

How do we get all the files in a folder, however? We use a loop. In automation, loops are important because they determine the control flow of a command. Loops will repeat a set of commands until a condition (known as a conditional is satisfied. Because we are using the command line, the scripting language we are using is known as bash (which stands for bourne again shell). In bash a loop takes this form:

for <variable> in <list>
do
	<command> $<variable>
done

To write your own loop, first open up a file ending with the .sh extension. Be sure to use a text editor not a word processor. Next we will add the hash-bang line, which tells the system how to run the file. Finally, we add in the command and control loop.

#!/bin/sh
for f in `ls *.jpg`
do
	convert -resize 800x $f $f-800.jpg
done

When we have finished writing the file, we need to make it executable with this command: chmod +x file.sh

Finnally, we can run our script with: ./file.sh. The script should now iterate through all of the files and perform the command on each one. You can check the directory by using ls *.jpg and ls *-800.jpg to check for all files and converted files, respectively.