Home / Alt manpages / ppmdraw(1)

  • ppmdraw(1)
  • User command
  • linux

Draw Lines, Shapes and Text on PPM Images with ppmdraw

You will create a small drawing script, apply it to a PPM image and verify the resulting image header. The examples draw a coloured rectangle, a line and a label without changing the original input. Allow about fifteen minutes if you already have a PPM image and know where the annotation should go.

You need the netpbm package and a shell. This guide describes the installed Netpbm 11.5.2 command; its manual page is dated 22 June 2005, so check the local manual if you are working with a substantially different release. The drawing itself normally needs no elevated privileges. Use sudo only when the input or output directory is genuinely protected, not as a default.

1. Check the command and choose an output file

Confirm that the executable is available before writing a script:

$ command -v ppmdraw
/usr/bin/ppmdraw
$ ppmdraw --version
ppmdraw: Using libnetpbm from Netpbm Version: Netpbm 11.5.2

The program reads one or more PPM images and writes the drawn images to standard output. Keep the source file intact and choose a new destination. Shell redirection with > truncates an existing destination before ppmdraw has succeeded, so do not point it at the only copy of a useful image.

2. Write a drawing script

Create a file named annotate.draw containing commands separated by semicolons:

setcolor red;
filledrectangle 10 10 160 35;
setpos 20 60;
text_here 12 0 "Sample image";
line 0 0 319 239;

There is one principal idea to keep in mind: coordinates are column first and row second. Column 0 is the left edge and row 0 is the top edge. The rectangle command takes the upper-left column and row, then its width and height. The line command takes the starting column and row followed by the ending column and row.

setcolor affects later drawing commands and accepts a Netpbm colour name. The default colour is white, so set it explicitly when the result needs to be repeatable. setpos changes the current position. text_here starts its baseline there and updates the current position after drawing. Its arguments are character height, baseline angle in degrees, and the text. Quoted text is one token when it contains spaces.

Checkpoint: inspect the script before running it. A missing semicolon can join two intended commands, and a row or column outside the image is simply off-canvas. Pixels drawn outside the canvas are discarded; that is not a cropping warning.

3. Apply the script to a PPM

Run the script against an input image and redirect standard output to a new file:

$ ppmdraw -scriptfile annotate.draw /path/to/input.ppm > annotated.ppm

A successful run is normally quiet and returns status 0. Check the status immediately, then inspect the output:

$ printf '%s\n' "$?"
0
$ file annotated.ppm
annotated.ppm: Netpbm image data, size 320 x 240, rawbits, pixmap

The exact wording from file can differ. The useful checks are that the file exists, is non-empty and has the expected dimensions. The output is a PPM image on standard output, so do not mix progress text into the same redirection.

4. Use an inline script for a small change

For a short, one-off operation, pass the script directly with -script:

$ ppmdraw -script='setcolor blue; line 0 0 319 239;' input.ppm > diagonal.ppm

The shell quoting keeps the semicolon inside the argument. A script file is easier to review and reuse, especially when it contains text, several colours or coordinates that need adjustment. You may use either a separate argument or an equals sign between an option and its value, and the manual permits the shortest unique option abbreviation. Full option names are clearer in saved commands.

5. Understand position-based commands

Use absolute commands when the geometry is known in advance:

circle 160 120 40;
line 20 20 300 20;

circle takes centre column, centre row and radius. spline3 takes six coordinates: start point, control point and end point. Neither line nor spline3 changes the current position.

Use relative commands when several marks should continue from one another:

setpos 20 80;
line_here 40 0;
line_here 0 20;
line_here -40 0;

Each line_here displacement is rightward and downward from the current point, and the command moves the current point to its endpoint. Negative values are allowed, although the corresponding point may be outside the canvas. Text begins on the baseline, and the initial current position is (0,0); set a useful position before using text_here or much of the lettering may sit above the image.

6. Diagnose failures without losing the original

If the command cannot open the image or script, check paths and permissions without changing anything:

$ ls -l /path/to/input.ppm annotate.draw
$ test -r /path/to/input.ppm && echo input-readable
input-readable

A parse error usually means a misspelled verb, missing argument, unmatched quote or missing semicolon. Compare the command with the documented verbs: setpos, setlinetype, setlineclip, setcolor, setfont, line, line_here, spline3, circle, filledrectangle, text and text_here. The two line-clip commands are not explained by the installed manual, so do not rely on undocumented settings for a repeatable example.

The input filename is optional. If you omit it, ppmdraw reads a PPM image from standard input:

$ ppmdraw -scriptfile annotate.draw < input.ppm > annotated.ppm

Do not also use -scriptfile=- in that form: the manual uses a dash to mean standard input for the script, and it cannot read both the script and image from standard input at once. The command supports multi-image PPM streams and applies the same script to each image in the installed release.

If you need to undo the example, delete only the newly created output and keep the input and script:

$ rm annotated.ppm

That removal is irreversible, so confirm the path with pwd and ls -l first when working in a directory containing valuable images.

Done means

  • ppmdraw reports the expected Netpbm installation.
  • The script uses explicit colours and coordinates that fit the image.
  • The original PPM remains unchanged.
  • The new file has a valid PPM header and expected dimensions.
  • You know whether each command changes the current position.