Adjust Netpbm Image Tones with pamlevels
You will remap the black and white points of a Netpbm image, write the result to a new PPM file, and check that the output is readable. The same method also supports a third point for a quadratic, gamma-like adjustment. 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.
This guide uses the installed Netpbm package, version 2:11.05.02-1.1build1 on the machine where it was checked. You need an input image in a Netpbm format that pamlevels can read, permission to read it, and enough space for a new output file. The examples do not need elevated privileges.
1. Check the command and choose a new output path
Confirm that the command is available and record the package version:
$ command -v pamlevels
/usr/bin/pamlevels
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
pamlevels reads an image from the named file, or from standard input when no file is supplied. It writes the transformed image to standard output. Redirect that output to a new path such as adjusted.ppm. Do not redirect over the source unless losing the original is acceptable: a shell redirection can truncate the destination before the program reports an error.
Checkpoint: substitute your own input name below, and pick an output name that does not already contain valuable data.
2. Apply a simple black-preserving adjustment
Two mapping pairs define a linear transformation in light intensity. The following keeps black black and maps a slightly darker white point to white, which brightens the upper part of the tonal range:
$ pamlevels -f1 black -t1 black \
-f2 white:0.9 -t2 white input.ppm > adjusted.ppm
The long forms are -from1, -to1, -from2 and -to2. The short forms used here are documented abbreviations. At least two complete mapping pairs are required. A colour can have an optional intensity scale after a colon, so white:0.9 means white at 0.9 times its intensity before it is mapped to the target.
There is no terminal message to interpret as success. A zero exit status means the command completed; the redirected file is the useful result. Check it without changing it:
$ printf 'pamlevels exit status: %s\n' "$?"
pamlevels exit status: 0
$ pamfile adjusted.ppm
adjusted.ppm: Netpbm image data, size 2 x 1, rawbits, pixmap
The dimensions and wording from pamfile depend on your input and Netpbm build. The important check is that the output is recognised as an image rather than an empty or unrelated file.
3. Set a white point explicitly
To correct a warm or otherwise uneven white point, map a specified RGB colour to white while keeping black fixed:
$ pamlevels -f1 black -t1 black \
-f2 rgbi:0.9/0.83/0.80 -t2 white input.ppm > white-point.ppm
$ pamfile white-point.ppm
Netpbm colour specifications can name colours such as black and white, or use forms such as rgbi:0.9/0.83/0.80. The numbers in this RGB specification are brightness values, even when the command is using an intensity-linear image mode. Keep the channel order and separators exact; a typo is more likely to produce a failed parse or an unintended colour than a useful correction.
4. Add a third point only when the curve needs it
A third mapping pair makes the transformation quadratic. This can compress or reshape the middle and upper tones:
$ pamlevels \
-f1 black -t1 black \
-f2 white -t2 white \
-f3 white:0.5 -t3 white:0.6 \
input.ppm > compressed.ppm
$ pamfile compressed.ppm
This is similar to gamma correction, but it is not a general colour-management workflow. Three anchors can also make an image look worse when they do not describe the desired tonal curve. Start with two pairs, inspect the result, and add the third pair only for a reason you can state in terms of the input and output points.
5. Choose the intensity model carefully
By default, the transformation is based on light intensity while the ordinary PPM representation is normally brightness, or gamma-adjusted. Use -linear only when the input is an intensity-linear PPM and you want the output in that same form:
$ pamlevels -linear \
-f1 black -t1 black -f2 white -t2 white \
linear-input.ppm > linear-output.ppm
This option does not convert an ordinary image into a physically correct linear representation. It requires the input to already be in the intensity-linear form and produces that form. Do not combine -linear with -fitbrightness; the installed manual says those functions cannot be used together because the brightness-fitting function is not implemented for the linear mode.
-fitbrightness instead applies the curve in brightness values. It is faster and can resemble what many other image tools do, but the manual describes it as normally undesirable because it has no physical basis. Use it only when matching an existing brightness-domain workflow is the actual requirement:
$ pamlevels -fitbrightness \
-f1 black -t1 black -f2 white -t2 white \
input.ppm > brightness-domain.ppm
6. Recover from a bad result
Keep the original input and compare each output before replacing anything in a wider workflow. If an output is wrong, remove or rename only the new file you created, then rerun with a different mapping. Do not delete the source as part of experimentation. If a command fails, inspect its diagnostic and exit status first; changing the mapping or input format is safer than adding sudo, which does not repair a malformed colour specification.
For a script, stop on failure before handing the output to another tool:
if pamlevels -f1 black -t1 black -f2 white -t2 white \
input.ppm > adjusted.ppm; then
pamfile adjusted.ppm
else
status=$?
printf 'pamlevels failed with status %s\n' "$status" >&2
exit "$status"
fi
If the redirection created an incomplete output before failure, treat that file as disposable and keep the source intact. A successful pamfile check confirms the file has a recognised Netpbm structure, not that the chosen tonal curve is visually correct.
Done means
- The installed Netpbm version and
pamlevelspath are known. - At least two complete mapping pairs are supplied.
- The source is preserved and the output is written to a deliberate new path.
pamfilerecognises the result as a Netpbm image.-linearis used only for intensity-linear PPM, and is not combined with-fitbrightness.- A third mapping pair is used only when a quadratic tonal curve is intended.