Scale PNM Images Fast with pnmscalefixed
pnmscalefixed resizes a PNM image to a width and height you choose, trading a little precision for speed. Allow about ten minutes to resize a test image, check the header, and see where the fixed-point maths can nudge an edge out of place. The input is never touched; only the output path changes.
The route
Jump straight to the step you need, or tick off Done means at the end.
1. Check the installed command
This guide uses the Netpbm command installed on this machine: Netpbm 11.5.2, Debian package 2:11.05.02-1.1build1. The manual page is dated 1 July 2020, so check the local manual before moving a script to another release.
$ command -v pnmscalefixed
/usr/bin/pnmscalefixed
$ pnmscalefixed --version
pnmscalefixed: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
pnmscalefixed: Built from source dated 2024-03-31 09:09:47
- It is the fast alternative to
pamscale. 12-bit fixed-point arithmetic beats floating point on speed but not on accuracy. - Reach for
pamscaleinstead when precision or extra features matter more than raw speed; it also has a-nomixoption thatpnmscalefixeddoes not.
2. Scale to exact output dimensions
Use -xsize and -ysize (also spelled -width and -height) when you know the target dimensions. This example halves a four-column test image and doubles its height:
$ pnmscalefixed -xsize 2 -ysize 6 /path/to/input.pgm > /path/to/output.pgm
Supply both values and they are treated independently, so the aspect ratio can change. If the source shape matters, work out the matching dimension yourself before typing both numbers.
Checkpoint
Inspect the result before using it anywhere else.
$ file /path/to/output.pgm
$ head -n 3 /path/to/output.pgm
P5
2 6
255
Netpbm may pick a binary encoding, so file is safer than reading the whole image in a terminal. Look for a non-empty file, the dimensions you asked for, and a valid PNM header; do not treat the pixel bytes after the header as text.
3. Scale by a factor instead of a size
Use -xscale and -yscale when the requirement is a ratio, not an absolute size. A factor of 2 doubles a dimension; 0.5 halves it:
$ pnmscalefixed -xscale 0.5 -yscale 0.5 /path/to/input.pgm > /path/to/half-size.pgm
$ file /path/to/half-size.pgm
/path/to/half-size.pgm: Netpbm image data, size 640 x 480, rawbits, greymap
Your own dimensions will differ; treat the example above as a shape, not a promise. Some rules worth remembering:
- One scale factor only? The other dimension stays as it is.
- One absolute dimension only? The other is adjusted to keep the aspect ratio.
- Both absolute dimensions supplied? That deliberately overrides ratio preservation.
The older -xysize and -pixels options still exist. Use the full option names in scripts so a later reader can see what was intended, and check the installed manual before relying on the less common forms.
4. See the fixed-point calculation
Add -verbose to see what the command actually worked out. Diagnostics go to standard error while the scaled image still goes to standard output:
$ pnmscalefixed -xsize 2 -ysize 6 -verbose /path/to/input.pgm > /path/to/output.pgm
pnmscalefixed: Scaling by 2048/4096 = 0.500000 horizontally to 2 columns.
pnmscalefixed: Scaling by 8192/4096 = 2.000000 vertically to 6 rows.
That denominator, 4096, is the command's 12-bit fixed-point arithmetic showing through. When your requested factor is an exact multiple of 1/4096, the manual says there is no fixed-point distortion at all; doubling and halving both qualify. Other ratios can push one input edge pixel into slightly more output space than it deserves, usually at the right or bottom edge.
That is a precision boundary, not a broken conversion. Invisible for a thumbnail, worth a second look for measurement work, repeated resampling, or anything where edge placement matters. Compare against pamscale and pick whichever meets your accuracy bar.
5. Protect an existing output file
Warning
Shell redirection with > truncates its destination the instant pnmscalefixed starts, before anything is checked. Write to a temporary name first, verify it, then swap it in:
$ pnmscalefixed -xsize 640 -ysize 480 /path/to/input.pgm > /path/to/output.pgm.new
$ test -s /path/to/output.pgm.new
$ file /path/to/output.pgm.new
$ mv /path/to/output.pgm.new /path/to/output.pgm
That final mv is the step that actually replaces the old file, so double-check the path before running it. If the conversion fails or the dimensions look wrong, leave the original alone and just remove the .new file. Once a good replacement has happened, the only way back is a backup or a snapshot; pnmscalefixed has no undo.
None of this needs elevated privileges. Reach for sudo only if the input or output directory is genuinely off-limits to your account, and check the path first.
6. Diagnose the common failures
An error opening the input almost always means a wrong path or unreadable file. Check without changing anything:
$ ls -l /path/to/input.pgm
$ test -r /path/to/input.pgm && echo readable
- Header dimensions look wrong? Check you did not mix up absolute sizes and scale factors:
-xsize 640means 640 columns,-xscale 640means a factor of 640, which is a very different request. - Image looks stretched? Both absolute dimensions were probably supplied without preserving the source ratio.
- Only one edge looks displaced? Rerun with
-verbose, compare the factors, and for a precision-sensitive job run the same request throughpamscaletoo.
Keep the original input around until the chosen output has been checked properly.
Done means
- Version confirmed:
pnmscalefixedis installed and its Netpbm version is known. - Input untouched: the output header shows the dimensions you intended.
- Method chosen deliberately: absolute dimensions or scale factors, with the aspect-ratio consequences understood.
- Precision checked:
-verbosewas used when fixed-point rounding or edge distortion mattered. - Existing output protected: nothing was truncated or replaced until the new file was verified.