Shift Image Colours Safely with pamhue
pamhue spins every colour in a Netpbm image around the HSV colour wheel by whatever angle you give it. It writes a new file and leaves the source alone. This guide uses pamhue from Netpbm 11.5.2, installed here as package version 2:11.05.02-1.1build1. Give it about ten minutes if your input image is already sitting ready.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need the netpbm package, a readable PBM, PGM, PPM or PAM image, and write access to wherever you plan to save the result. These are ordinary user commands: no sudo, and pamhue never touches system configuration.
1. Check the installed command
Make sure the command your shell finds is the one you think it is, then note the linked Netpbm version:
$ command -v pamhue
/usr/bin/pamhue
$ pamhue -version
pamhue: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
...
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
The exact -version wording carries build details that vary, and the package version differs between distributions. What actually matters here is that pamhue reports a Netpbm library and the binary exists at all.
Checkpoint
If command -v finds nothing, stop and install Netpbm through your normal package manager. Do not grab a binary from anywhere else.
2. Choose a new destination
pamhue takes one input filename and writes the processed image to standard output, so you redirect that to a different file. Never redirect back onto the source path unless you deliberately want the shell to wipe it out before pamhue even reads it.
$ INPUT='/path/to/source.ppm'
$ OUTPUT='/path/to/source-hue-120.ppm'
$ test -r "$INPUT" && echo "input is readable"
input is readable
Those shell variables are just placeholders: swap in your real paths. A path with spaces stays safe as long as it is inside double quotes.
3. Shift colours clockwise
Pass the mandatory -huechange option with a degree value, then redirect standard output:
$ pamhue -huechange=120 "$INPUT" > "$OUTPUT"
A positive value moves clockwise: 120 degrees turns red towards green, green towards blue and blue towards red, applying the same angular shift to every pixel in the image. The value can be fractional, or larger than one full revolution.
pamhue has no progress output, because the image data is the output stream itself. Check the exit status and the destination straight away:
$ printf 'pamhue exit status: %s\n' "$?"
pamhue exit status: 0
$ test -s "$OUTPUT" && echo "output is non-empty"
output is non-empty
$ file "$OUTPUT"
/path/to/source-hue-120.ppm: Netpbm image data, size = 640 x 480, rawbits, pixmap
Your own file description will read a little differently. Just confirm it names a Netpbm image with dimensions matching the source, then keep the original until you have looked the result over.
4. Try a counterclockwise or precise shift
Negative values move counterclockwise. Whitespace can stand in for the equals sign, but the equals form scans more easily in scripts:
$ pamhue -huechange=-120 "$INPUT" > /path/to/source-hue-minus-120.ppm
$ pamhue -huechange=22.5 "$INPUT" > /path/to/source-hue-22-5.ppm
$ pamhue -huechange=480 "$INPUT" > /path/to/source-hue-480.ppm
There is no special wraparound syntax to learn: pamhue is happy with angles past 360 degrees. Name each output after the angle used and keep every run separate, especially when you are comparing variants side by side.
5. Understand grayscale and source safety
Hue means nothing in a black-and-white or grayscale image, so pamhue leaves those unchanged in visual content. A hue shift is not a colourisation trick for a PGM or PBM file; reach for a proper colourisation or compositing workflow for that.
pamhue only ever writes a new stream, never the input file in place. The real risk is the shell's own redirection: > opens and truncates its destination before pamhue has even started. To replace an existing output only on success, write to a temporary name in the same directory first:
$ TEMP='/path/to/source-hue-120.ppm.new'
$ pamhue -huechange=120 "$INPUT" > "$TEMP" && mv -- "$TEMP" "$OUTPUT"
$ file "$OUTPUT"
If pamhue fails, && stops mv from ever touching the old output. Check the error before you inspect or delete the incomplete temporary file. Your original input is still your recovery copy either way.
6. Diagnose the common failures
The angle is mandatory. Leave it out and the command exits with status 1, telling you exactly what is missing:
$ pamhue "$INPUT" > /tmp/pamhue-missing-option.ppm
pamhue: You must specify -huechange
$ printf 'exit status: %s\n' "$?"
exit status: 1
A file created by a failed redirection is not a valid result, whatever its name suggests. Use the temporary-file pattern above whenever the output actually matters.
If pamhue cannot open the input, check the path and permissions without changing anything:
$ ls -l -- "$INPUT"
$ test -r "$INPUT" && echo readable || echo 'not readable'
If the output is not recognised as Netpbm, check the exit status before you open it. A pipeline can hide an earlier failure unless you turn on set -o pipefail; for a plain redirection, the immediate $? is the status that matters.
Done means
- Confirmed the binary.
pamhueis the expected Netpbm build and its version is known. - Supplied the angle.
-huechangecarries the intended positive, negative or fractional value. - Checked the output. It is a non-empty Netpbm image with dimensions matching the input.
- Kept the source. The original image is untouched, and important replacements went through a temporary file.
- Handled grayscale correctly. A grayscale input was treated as unchanged, not as colour data to shift.