Find Exact Pixel Tuples and Colours with pamfind
pamfind locates every pixel in a Netpbm image matching a tuple, given as decimal samples or a named colour. Allow about ten minutes if the image is already in PNM or PAM format; the result is a list of row and column coordinates ready for a script.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need the netpbm package and a readable PNM or PAM file. These examples were checked with package version netpbm 2:11.05.02-1.1build1. The command only reads its input and writes coordinates to standard output, so it does not alter the image and elevated privileges are not normally needed.
1. Check the installed command and image
Confirm the executable is available and identify the input before searching it:
$ command -v pamfind
/usr/bin/pamfind
$ file /path/to/image.ppm
/path/to/image.ppm: Netpbm image data, size 3 x 2, pixmap
Your file description will vary; the point is confirming the input is a Netpbm image such as PPM, PGM, PBM or PAM. If it is another format, convert it with a suitable Netpbm tool first, and keep the original while you check the conversion.
Checkpoint
You have a real input path and can read it without sudo. If file reports a different format, stop and convert or choose the correct input.
2. Search for an exact tuple
Use -target when you know the sample values. Give them in tuple order, exactly as many as the image depth requires. For an RGB image, red at the maximum sample value is normally 255,0,0:
$ pamfind -target=255,0,0 /path/to/image.ppm
Locations containing tuple (255/0/0)/255:
(0, 0)
(0, 2)
(1, 1)
Coordinates print as row and column, starting at zero. The heading shows the requested tuple and the image's maximum sample value; the sample output above came from a three-column, two-row PPM containing three red pixels. Your coordinates will depend on the image.
A search with no matches is still a successful search: it prints the heading and no coordinate lines, and returns status 0. Do not read an empty result as proof the image is empty, only that the requested tuple was not found.
3. Search by a named colour
For a visual colour image, the named-colour option is often clearer than decimal samples:
$ pamfind -color=red /path/to/image.ppm
Locations containing tuple (255/0/0)/255:
(0, 0)
(0, 2)
(1, 1)
Netpbm's colour parser interprets the name. Use this mode only when the input has depth 3: the program rejects a depth-1 greyscale image outright rather than pretending its single samples are RGB.
$ pamfind -color=red /path/to/greyscale.pgm
pamfind: You specified -color, but the input image has depth 1, not 3
If a depth-3 image contains data that is not really visual RGB, named-colour mode still treats its tuples as colours regardless. Use -target when the samples mean something else, or when you need exact values without colour-name parsing getting involved.
4. Produce coordinates for a script
Add -machine when another program will consume the result. It drops the explanatory heading and prints one zero-based row and column pair per match:
$ pamfind -target=255,0,0 -machine /path/to/image.ppm
0 0
0 2
1 1
Same information as the human-readable form, not a different search. A simple shell loop can consume the two fields:
pamfind -target=255,0,0 -machine /path/to/image.ppm |
while read -r row column; do
printf 'red pixel at row=%s column=%s\n' "$row" "$column"
done
Keep the command's exit status separate from whether any lines printed. A valid search with zero matches still returns success, so check for output when you need to know whether a match exists.
5. Avoid the option and input traps
Specify exactly one of -target and the named-colour option: omitting both, or supplying both, is a command-line error. Do not guess the number of target samples either: an RGB image needs three values, a greyscale image needs one, and target values must use the image's own sample scale. An image with a maximum other than 255 will not treat 255,0,0 as the same tuple as 1,0,0.
The input image is optional in the synopsis, meaning standard input works too. That is handy for a pipeline, but it can also make a typo look like a stalled command while the program waits for data that never arrives. Pass an explicit filename while testing:
$ pamfind -target=0,0,0 /path/to/image.ppm
When a pipeline is intentional, make its source obvious and check the producer separately:
$ pamcut -left=5 -top=7 -width=1 -height=1 /path/to/image.ppm | pamfind -target=0,0,0
This searches the one-pixel image pamcut emits; it does not ask pamfind to inspect the original coordinates. To inspect the tuple at a known location instead, the manual's usual pattern is pamcut followed by pamtable.
6. Recover from a failed search
Verify the path and readability first, without changing anything:
$ test -r /path/to/image.ppm && echo readable
readable
$ file /path/to/image.ppm
Then check the image's format and depth with an appropriate Netpbm inspection tool, or retry with a known-good PPM. If named-colour mode fails on depth 1, switch to a one-sample -target or use a genuine depth-3 image. If coordinates look wrong, confirm you are reading row and column in that order, and that the target's sample scale matches the input.
There is no undo operation because pamfind makes no state change. If you created an intermediate conversion file, remove only that file once you are sure no later command needs it. Do not delete the source image as part of troubleshooting.
Done means
- Command and image confirmed: pamfind and the input PNM or PAM image are available to the current user.
- One search mode used: exactly one of
-targetand the named-colour option, with the right tuple depth. - Coordinates understood: zero-based row and column values, read in that order.
- Script-friendly output when needed:
-machineused when a script needs one pair per line. - Empty result distinguished: an empty match list is told apart from a command or input failure.