Introduction: Add Text to Images With Linux 'convert' Command

This instructable will show you how to add text to an image using the convert command in Linux. One valuable use of this is the placing of a caption on an image for documentation. Another use would be the placing of a time stamp on an image that gets generated automatically by a webcam.

There are many convert options that you can make use of in placing text on the image. You can choose the starting point for the text (via a height/width coordinate), the fill color of the text, the point size of the text, and the font used. This instructable will show you how to do all this.

The major catch with this instructable is that you have to do all this in the Linux operating system. I'm not aware of a utility such as convert in Microsoft Windows but who ever does anything with a command line in Windows? This instructable is more aimed at Linux users who want to get more out of their computer. If you are a Windows user and are still tempted to read this instructable, you may be tempted to download and install Linux. I may write an instructable on how to do this at a later date but if you want to pursue this on your own, you can go to http://www.ubuntu.com/ and start the process. You can turn your computer into a dual-boot machine (I'd really recommend that you install a second hard disk in your machine -- any size will do). BTW, Linux is FREE, along with everything available to it. Also, so far, it is invulnerable to viruses.

Step 1: The Linux 'convert' Utility

To perform the task of adding a label to an image, we will be working entirely within a Linux terminal window. Windows calls this a command window but it is rarely used in Windows except by oldtimers who remember it from the DOS days. Linux users make heavy use of it.

First of all, bring up a terminal window. With Ubuntu Linux, you do this by selecting Applications->Terminal. A window will open up with a command line prompt. It will put you at your home directory.

Let's assume that the image you want to play with is in an "images" subdirectory. To get to that subdirectory, type "cd images". Issue the comman "ls" to see what files are there. In my case, I want to work with a file called "sunset1.jpg".

You also want to make sure that the convert command is available on your system. One way to do this is to issue the command "which convert". If it is available, its location will be printed to the screen. In my case, it is at "/usr/bin/convert". Another way to find out if it is available, just issue the command "convert" at the command line. If it is there, a long description of the command will be printed out with all the options available. If it is not there, you will see "convert: command not found". Let's assume that it is available.

If you issue the bare command "convert" you can see that it is a very powerful tool with many capabilities. A more complete description of the convert command can be found at:
http://linux.about.com/od/commands/l/blcmdl1_convert.htm

For our purposes, we only want to use the "-draw" argument to write the caption to the photo.

Step 2: Adding a Caption

My original image will be a file called sunset1.jpg. This is a photo that I took on a recent trip to Egypt and Jordan
(You can see all the photos at http://www.datasink.com/egypt2009.shtml ).
I will keep the original image in place and save changes to new filenames for safety sake.

The original image is a scaled down version of a much larger image that was a 7 megapixel image. I used another capability of the "convert" command to resize it a smaller version for this instructable. This image is 640x480. That means that it is 640 pixels wide and 480 pixels tall. We will use this information to determine where we want to place the caption.

Here is a command that produces sunset2.jpg:

convert -pointsize 20 -fill yellow -draw 'text 270,460 "Sunset over the Nile" ' sunset1.jpg sunset2.jpg

Note:
-pointsize 20: this is the size of the letter (there are 72 points per inch)

-fill yellow: this is the fill color of the text

-draw 'text 270,460 "Sunset over the Nile" ': start 270 pixels from the left and 460 pixels from the top

sunset1.jpg sunset2.jpg: using the first file as a starting point, write out to the second file

There is a wide range of color names that you can specify. If you enter the command "showrgb", you will see the long list of color names available (isn't Linux great?).

The -draw argument has to be treated carefully. After -draw you start the argument with a single quote. You then put put the horizontal and vertical coordinates of where you want to the text to start. If you put a coordinate that is larger than either dimension, the text won't show up. Finally, you put the caption in double quotes. Make sure to end the whole argument with a closing single quote.

The two last arguments (sunset1.jpg sunset2.jpg) indicate that you want to use sunset1.jpg as the starting point and want to write the results to sunset2.jpg. If you had put sunset1.jpg sunset1.jpg, it would modify the original copy of the image.

Once you issue this command, you should see the file sunset2.jpg show up in your photos directory. If you want to, you can put as many chunks of text as you want on the image. Just keep adding them to sunset2.jpg file.

Note that there is a font argument that you can also use. For example, you can insert "-font helvetica" after the "convert". Your Linux system has a whole library of fonts. Mine are located at "/var/lib/defoma/gs.d/dirs/fonts/". I count over 170 of them there. Instead of using "-font helvetica" I might use something like "-font /var/lib/defoma/gs.d/dirs/fonts/Loma-BoldOblique.ttf". These are fun to play with.

You can can use the Coordinate Map for the approximate horizontal and vertical coordinates that would apply to an image that is 640x480. The markup on this image was created using the convert utility.

Step 3: Automating the Labeling of Images

You have seen how you manually add a caption to an image from the command line. This works fine if you just have a few photos to work with but it can be pretty tedious to work this way. If you have a whole lot of images to process, you might want to make use of some sort of scripting language in Linux. One possibility is to use a shell script. What I use is a scripting language called Perl. This is what I use for all kinds of CGI scripts on the web. Other possibilities are Java, C++, PHP, and Python. Whatever you use, you have to be able to create a command line string and the shell out to execute it.

One way that I make use of this is where I automatically put the timestamp on an image that my webcam generates once a minute. In a Perl script I formulate the current timestamp (date and time) and then overlay it on the current image. I also put my website address on the photo. You can see that the attached image was taken on February 2 at 13:07. I have a script on my computer that runs once a minute. It grabs the image from the webcam, inserts the website name and timestamp, and then uploads it to my website. You MAY be able to see this in action at http://www.datasink.com/webcam.shtml. I say "may" because this only happens when my computer is turned on. I don't leave it on overnight or when I am away.

If I wanted to label a whole directory of images, I would create a Perl script to do it. One way to do this is to create a text file that has the whole list of images in the directory, one per line. Following the image name on each line would be the text of the caption. I would create a loop that would take the label and apply it to the image. Of course, there would be a problem of getting the label centered horizontally. I would probably have to calculate the actual width of the caption and then adjust the horizontal argument.