Colourise a PGM Image with pgmtoppm Without Losing Tonal Detail
You will finish with a colour PPM made from a greyscale PGM, with the black and white endpoints under your control and the output checked for the expected format and depth. The examples use Netpbm 11.5.2, installed here as Debian package netpbm 2:11.05.02-1.1build1. Allow about ten minutes if Netpbm is already installed.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a readable PGM file and the commands pgmtoppm, pnmfile, and, for the depth example, pamdepth. These are ordinary user commands. Nothing in this guide needs sudo, and the input image is never changed.
1. Check the installed command
Confirm which executable will run and record its Netpbm version. This catches a surprisingly common distraction: reading documentation for one installation while a different binary is first in your PATH.
$ command -v pgmtoppm
/usr/bin/pgmtoppm
$ pgmtoppm -version 2>&1 | head -4
pgmtoppm: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
pgmtoppm: Built from source dated 2024-03-31 09:09:47
pgmtoppm: Built by Debian
pgmtoppm: BSD defined
Checkpoint: if command -v finds nothing, install Netpbm through your normal package-management process before continuing. Do not solve a missing command by running the converter as root.
2. Convert with explicit endpoint colours
pgmtoppm reads a PGM and writes a PPM to standard output. The -black value replaces input black, -white replaces input white, and intermediate grey values are interpolated between those colours. Redirect the output to a new name first so the source remains available:
$ pgmtoppm -black=navy -white=white /path/to/input.pgm > /path/to/colourised.ppm
$ pnmfile /path/to/colourised.ppm
/path/to/colourised.ppm: PPM raw, 1024 by 768 maxval 255
The dimensions in the sample output are illustrative. Your file should report the input dimensions, a PPM format, and a maxval matching the input unless you use -map. A non-zero exit status means the conversion failed, so inspect the input path and permissions before inspecting the image.
Do not use a destination that contains the only copy of a valuable image. Shell redirection truncates an existing file before pgmtoppm starts. If you must replace an existing output, use a temporary destination and move it into place only after verification:
$ pgmtoppm -black=navy -white=white /path/to/input.pgm > /path/to/colourised.ppm.new
$ pnmfile /path/to/colourised.ppm.new
$ mv /path/to/colourised.ppm.new /path/to/colourised.ppm
The final mv replaces the old destination, so treat it as the deliberate state-changing step. Before it, remove the .new file if the check fails. If the move has already happened, restore the previous file from your backup or snapshot; there is no undo operation supplied by pgmtoppm.
3. Understand the maxval trap
PGM stores samples from zero to its declared maxval. Without -map, the PPM produced by pgmtoppm keeps that maxval. A low-depth source therefore cannot express many subtle output colours, even when you request a vivid endpoint colour.
For example, this one-bit PGM produces a PPM whose maxval is still 1:
$ printf 'P2\n2 1\n1\n0 1\n' | pgmtoppm red | pnmfile
stdin: PPM raw, 2 by 1 maxval 1
If the source needs more tonal resolution, raise its depth in the pipeline before colourising it. The following keeps the same two pixels but gives the output 256 representable levels:
$ printf 'P2\n2 1\n1\n0 1\n' | pamdepth 255 | pgmtoppm red | pnmfile
stdin: PPM raw, 2 by 1 maxval 255
Use a depth suitable for the image and the next tool. The manual also documents pamdepth 16; 255 is a straightforward general choice. This changes the streamed copy, not the original file.
4. Use the historical shorthand when it helps
The explicit options are easiest to review, but the command also accepts a colour argument. A single colour sets the white endpoint and leaves black at its default. A pair separated by a hyphen sets both endpoints:
$ pgmtoppm black-red /path/to/input.pgm > /path/to/red-scale.ppm
$ pnmfile /path/to/red-scale.ppm
/path/to/red-scale.ppm: PPM raw, 1024 by 768 maxval 255
Keep the explicit form in scripts when a colour name or specification might contain punctuation. Netpbm accepts colour specifications understood by its colour parser; simple names such as navy, red, and white are easier to audit than an unexplained numeric string. The installed manual permits a space instead of =, and accepts double hyphens, but full spelling with = is clearer:
$ pgmtoppm --black navy --white white /path/to/input.pgm > /path/to/colourised.ppm
5. Apply a multi-colour map when two endpoints are not enough
Use -map when the scale needs several deliberate colours. The map is a PPM file; its pixels are used in order, with black mapped to the first colour, white to the last, and values between them spread across the sequence. Its maxval becomes the output maxval.
$ pgmtoppm -map=/path/to/heatmap.ppm /path/to/input.pgm > /path/to/heatmap.ppm.out
$ pnmfile /path/to/heatmap.ppm.out
/path/to/heatmap.ppm.out: PPM raw, 1024 by 768 maxval 255
Do not combine -map with -black or -white. If you need exact per-level assignments rather than interpolation across a map, use pamlookup and create its index file according to that command's documentation.
6. Diagnose the result before handing it on
Run pnmfile after every conversion that matters. Confirm the file is non-empty, the dimensions match the source, the format is PPM, and the maxval is high enough for the colours you chose. If a downstream program only needs to read the image as PPM, remember that Netpbm PPM readers can generally accept PGM directly. For a plain format conversion with no colourisation, ppmtoppm is the more direct tool.
If the result is unexpectedly flat or nearly black, check the source maxval first. A maxval of 1 or another small value can quantise away intermediate colours. If the command rejects a colour, try a simple named colour such as red, then consult the installed pgmtoppm(1) and colour-parser documentation for the exact specification you want. If it cannot open the input, check ls -l and test -r; elevated privileges should not be the first response.
Done means
pgmtoppmis the expected Netpbm installation and its version is known.- The PGM remains untouched and the destination is a verified PPM.
- Black and white endpoint colours are explicit, or the shorthand choice is understood.
- The output maxval is high enough to preserve the intended tonal detail.
- A map file is used only when a multi-colour scale is needed, without endpoint options.
- No command was run as root, and an existing output was not overwritten accidentally.