Scripted drawing with ImageMagick

Silhouette

Article from Issue 263/2022
Author(s):

ImageMagick can do more than just edit existing images. The free software can even be scripted to create simple drawings.

Although you would normally use a bona fide graphics program for drawing and painting, there are definitely situations in which you need to draw regular shapes in an image repeatedly at fixed intervals – as shown here, for example, when creating the silhouette of an imaginary city (Figure 1). This does not require an expensive graphics program with a sophisticated macro language. Using the free and open source ImageMagick software package at the command line is more than up to this task.

Figure 1: Picture of a skyline created with ImageMagick. You can pass in the number of windows and floors as parameters.

To compose more extensive images, you will need the support of a scripting language such as Bash, which uses loops and other control structures to repeatedly insert image content into the graphic. ImageMagick can be found in the package sources of most Linux distributions, but it can also be downloaded for installation from the download section of the project page [1].

Painting by Commands

After completing the install, type

magick logo: logo.gif

at the command line. ImageMagick will create the logo.gif file in the current directory. It shows the magician seen in the upper right corner of Figure 1. You can easily check this by opening the file in a suitable image viewer. Image names ending with a colon are internal test images in ImageMagick. You can create more test images with the rose: and wizard: [2] options.

To demonstrate that you can actually draw at the command line with ImageMagick, see the command in Listing 1.

Listing 1

Rectangle

 

What this does is to first set the image size with the -size parameter. Then xc:skyblue paints the background of the image sky blue. Historically, xc: stands for "X Constant Image," but today it stands for canvas. The instruction expects a color name from the X Window System palette, which ImageMagick adopted [3].

You can also specify a gradient, for example, by typing gradient:blue instead of xc:skyblue. The built-in gradient image generator would then create a blue gradient background image for you. For an idea of the possibilities, check out the ImageMagick documentation. The manual goes into the details of plasma canvases [4] and gradients [5], for example.

The -fill parameter is followed by the definition of the drawing color for the subsequent drawing command, which is introduced by -draw and quoted. The last parameter is the name of the image file to be created.

The resulting image is a red rectangle, rounded at the corners, on a light blue background. You create more complex drawings by stringing together several drawing commands (Listing 2, lines 1 to 3).

Listing 2

Multiple Elements

 

Three-Box Car

The result of the first call from Listing 2 is shown in Figure 2: a very simplified image of a notchback based on the three-box principle. By passing in the drawing command from line 4 of Listing 2, you can improve the boxy shape a little. The command angles the passenger compartment a bit at the front.

Figure 2: A notchback created with simple draw commands.

The auto.png file I just created provides the basis for subsequent beveling of the passenger compartment. The command writes the results to the auto-bevel.png file. If you want to avoid constantly recreating files, use the command from the last line of Listing 2 instead. This modifies the auto.png file directly.

Although both methods have advantages for your first steps in getting to know ImageMagick, they have one decisive disadvantage. They are both comparatively slow. As you can imagine, drawing an entire skyscraper this way is complicated. You would have to string together several draw commands, and a separate call would be required for each individual window. And you would have to manually calculate the positions of the windows up front.

Faster with Scripts

The slowness in drawing a skyscraper can remedied by using a script that determines the image size based on the information it receives about the desired number of floors and windows per floor. It also defines a color gradient for the background and saves the image. It then calculates all the drawing instructions for the actual building and the windows and doors and collects them in an XML-formatted Magick Scripting Language (MSL) file.

Finally, the script uses a conjure statement to process the mess of drawing commands. This greatly improves speed over incrementally developing the image using individual mogrify statements. Listing 3 shows an MSL file for a small two-story house with a foundation, five windows, and a front door.

Listing 3

miniHouse.msl

 

You call the buildHouse shell script, on which this workshop is based, using the syntax in Listing 4. Its contents are taken unchanged from Listing 5. For the sake of simplicity, the script does not perform an extensive check of the parameters you pass in. In addition, only positioning parameters are used. The call sequence in the command line determines the assignment in the script for this. If you want to improve this script, you need to look into the shell's error checking options and also consider using getopts in the script.

Listing 4

Sample Syntax

 

Listing 5

buildHouse

 

When calling the script, you need to specify the file name without a file extension. The .msl and .png extensions are added automatically by the code. If you leave the option for the number of floors and the number of windows per floor empty, the script will use default values. The file name, on the other hand, must always be specified, otherwise the program will abort. You always need to append the number of floors and windows per floor together, otherwise the script will not evaluate the parameters completely and will replace both with default values.

Once you have made all the entries, you can optionally specify a fourth parameter for correcting the boundary distance to the neighboring property if you want to recreate the sample settlement from Figure 1 as shown in Listing 6. Table 1 explains the meaning of the assembly and composite tools, among other things.

Table 1

Command Line Tools in the ImageMagick package

Tool Name

Function

convert

A standard tool from the ImageMagick package, it can convert file formats and scale, blur, crop, denoise, dither, rotate, flip images, and much more.

identify

Outputs a description of the format and characteristics of one or more graphics files.

mogrify

Offers the same functions as convert, but unlike the latter, overwrites the source file.

composite

Overlaps two images.

assemble

Assembles multiple images into one.

compare

Displays the differences between two graphs (as a report of a mathematical analysis and visually).

stream

Copies single or multiple pixel components of an image to another format (mainly intended for very large image files).

display

Displays an image or image sequence via an X server.

import

Creates screenshots in X11. The function optionally saves the entire screen area, the area of a window, or a defined rectangle.

conjure

Interprets scripts in the MSL and executes them.

Listing 6

Building a Skyline

 

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.


News