Home / Alt manpages / ppmlabel(1)

  • ppmlabel(1)
  • User command
  • linux

Add Clear Text Labels to PPM Images with ppmlabel

You will finish with a labelled PPM image and a repeatable command for adding several labels in one pass. The examples use Netpbm 11.5.2, installed here as Debian package version 2:11.05.02-1.1build1. Allow about ten minutes if you already have a PPM file, or fifteen minutes for the small test image below.

You need a shell, the ppmlabel command and a writable output directory. This tool reads a PPM image and writes a PPM image. It does not edit the input file in place, and it does not need sudo.

1. Check the command and your input image

Confirm which executable will run, then inspect the image before changing anything:

$ command -v ppmlabel
/usr/bin/ppmlabel
$ pamfile INPUT.ppm
INPUT.ppm:    PPM raw, 160 by 90  maxval 255

Replace INPUT.ppm with the path to your own image. The dimensions and maximum value will vary. pamfile is a useful checkpoint because it confirms that you are feeding the program a PPM file, rather than a PNG or an image with a merely similar filename.

Checkpoint: keep the original input untouched and choose a different output path, such as OUTPUT.ppm. If you plan to replace an existing file, make a backup first:

$ cp -- INPUT.ppm INPUT.ppm.bak

That copy is your recovery path if the new image is misplaced or the output is not what you wanted. Shell redirection can truncate an existing destination before ppmlabel reports an error, so do not point > at your only copy.

2. Add one label at a chosen position

Run the command below with a separate output file:

$ ppmlabel \
    -x 10 -y 25 \
    -size 12 \
    -colour black \
    -text 'Inspection copy' \
    INPUT.ppm > OUTPUT.ppm
$ pamfile OUTPUT.ppm
OUTPUT.ppm:    PPM raw, 160 by 90  maxval 255

-x sets the column where the text is left justified. -y sets the baseline row, not the top edge of the letters, so descenders can extend below it. -size is the height in pixels of the tallest characters above the baseline. -colour accepts a Netpbm colour name, and -text draws the supplied string.

Text containing spaces must be quoted as one shell argument. Single quotes are convenient for ordinary labels; use double quotes when you need shell expansion, and understand that expansion happens before ppmlabel receives the text.

3. Add several labels without repeating coordinates

Options are commands applied from left to right. A setting affects the text that follows it, and each -text advances the next label down by 1.75 times the current text size:

$ ppmlabel \
    -x 10 -y 25 -size 12 -colour black \
    -text 'Sample image' \
    -text 'Captured 2026-09-26' \
    INPUT.ppm > OUTPUT.ppm

This is useful for a short caption block. The automatic spacing is not a general layout engine: long text can run beyond the image, and rotated text can overlap later lines. If exact placement matters, set -x and -y again before each label.

Checkpoint: inspect the output dimensions and open it with an image viewer that understands PPM. A successful pamfile result proves the output format is readable, but it cannot tell you whether a label is inside the visible part of the image.

4. Choose a background and rotate the baseline

By default the label is drawn over the existing pixels. Make that explicit with -background transparent, or request a coloured rectangle behind subsequent text:

$ ppmlabel \
    -x 10 -y 25 -size 12 \
    -colour white -background navy \
    -text 'Night shift' \
    INPUT.ppm > OUTPUT.ppm

The background rectangle encloses each following text item. With multiple lines, the manual warns that the space between lines may not be filled correctly, especially when the text is rotated. Use a transparent background when preserving the underlying image matters, or test the coloured version visually before distributing it.

Set a counterclockwise baseline angle for later text with -angle:

$ ppmlabel \
    -x 30 -y 70 -size 14 -colour red \
    -angle -30 -text 'Draft' \
    INPUT.ppm > OUTPUT.ppm

Angles are integral degrees measured counterclockwise from the image row axis. Keep the starting coordinates away from the edges because rotation changes the space the label occupies.

5. Read labels from a file or standard input

-file reads lines from a named file and draws them on successive lines. This avoids putting a long caption into the shell command:

$ ppmlabel -x 10 -y 25 -size 12 -colour black \
    -file labels.txt INPUT.ppm > OUTPUT.ppm

Each line is treated as text. The font is limited to 7-bit ASCII, so accented letters and other 8-bit characters are not supported by this tool. Convert or simplify the text before running it; do not assume that quoting will make non-ASCII characters render correctly.

If you omit the input filename, ppmlabel reads the PPM image from standard input. The output is still standard output:

$ cat INPUT.ppm | ppmlabel -x 10 -y 25 -text 'From stdin' > OUTPUT.ppm
$ pamfile OUTPUT.ppm
OUTPUT.ppm:    PPM raw, 160 by 90  maxval 255

For a script, prefer a direct redirection such as ppmlabel ... < INPUT.ppm > OUTPUT.ppm. It states both streams clearly and avoids an unnecessary process.

6. Diagnose the usual failures

A missing input file produces a non-zero status and an error on standard error. Check the status immediately:

$ ppmlabel -text 'Test' missing.ppm > OUTPUT.ppm
ppmlabel: Unable to open file 'missing.ppm' for reading. ...
$ printf 'exit status: %s\n' "$?"
exit status: 1

The exact diagnostic includes the system error and may vary. A status of 1 means the command failed; it is not a reason to trust a partially written output. Check the input path, permissions and format, then write to a fresh destination.

If text is clipped, move the baseline inward, reduce -size, shorten the label or use a smaller angle. If a colour is rejected, use a recognised Netpbm colour name such as black, white, red or navy. Do not rely on a viewer's ability to display the result as proof that the label is positioned well.

For more complex overlays, the manpage points to pbmtext or pbmtextps combined with pamcomp, and to ppmdraw for general drawing. Those tools are better choices when you need a designed text layer, fonts outside ppmlabel's fixed font, or precise composition.

Done means

  • You confirmed that the input is a readable PPM image.
  • You wrote the labelled result to a separate output path.
  • You can explain that -y marks a baseline, not a top edge.
  • You used left-to-right option order for multiple labels.
  • You tested background and rotation when those features mattered.
  • You verified the output with pamfile and kept a backup before replacing any original.