Resize Netpbm Images Predictably with pamscale
pamscale resizes a Netpbm image on the command line, and getting the aspect ratio and exact pixel count right first time saves a second pass later. The examples use pamscale from Netpbm 11.5.2, provided here by package netpbm 2:11.05.02-1.1build1.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell, the Netpbm tools and a PNM, PGM, PPM or PAM input image. The commands write new files in the current directory and need no elevated privileges unless the directory or source is protected. Do not use sudo just to scale an image.
1. Check the installed command and source image
Confirm which executable will run, then inspect the input's current dimensions:
$ command -v pamscale
/usr/bin/pamscale
$ pamscale --version
pamscale: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
$ pamfile /path/to/source.ppm
/path/to/source.ppm: PPM raw, 400 by 300
The exact pamfile wording depends on the input format. If the file is not a Netpbm image, convert it first with an appropriate Netpbm converter. pamscale reads standard input or a named file and writes the scaled image to standard output, so redirecting to a new name is the safe pattern that keeps your original intact.
Checkpoint
Pick a source such as /path/to/source.ppm and a destination such as scaled.ppm. If the destination already holds something useful, choose another name: shell redirection truncates an existing file before pamscale gets a chance to warn you.
2. Preview an aspect-preserving fit
Use -xyfit when an image has to fit inside a bounding box without distortion. This plans the largest result that fits within 800 by 600 pixels, but creates nothing yet:
$ pamscale -xyfit 800 600 -reportonly /path/to/source.ppm
400 300 1.000000 1.000000 400 300
The six fields are input width, input height, horizontal factor, vertical factor, output width and output height. The sample line above is for a 400 by 300 source; your numbers will differ. -reportonly emits one line per input image and sends no scaled image to standard output.
- Source larger than the box. Both factors will normally come out below 1.
- Source already smaller than the box. The fit can leave it unchanged, because pamscale never enlarges just to fill a bounding box.
Checkpoint
Run the report first, every time. Only move on when the final two numbers suit the application that will consume the image.
3. Write the fitted image to a new file
Repeat the same options minus -reportonly and redirect standard output:
$ pamscale -xyfit 800 600 /path/to/source.ppm > fitted.ppm
$ pamfile fitted.ppm
fitted.ppm: PPM raw, 400 by 300
On a source that doesn't already fit, pamfile will show the reduced dimensions. The aspect ratio survives because only the fit box, not independent width and height values, drives the scale.
Recovery
There is no in-place undo. Wrote to the wrong destination? Remove only that newly created file after checking its path, or restore the destination from your normal backup. Never run a broad wildcard such as rm *.ppm to clean up a mistake.
4. Choose exact dimensions or one dimension
Use -width and -height for absolute output dimensions. Supply both and pamscale scales them independently, which can stretch the image:
$ pamscale -width 800 -height 600 /path/to/source.ppm > exact.ppm
$ pamfile exact.ppm
exact.ppm: PPM raw, 800 by 600
- Supply only one absolute dimension and pamscale calculates the other to preserve the aspect ratio.
-xsizeand-ysizeare equivalent names for width and height. Prefer the clearer-widthand-heightin new scripts.- A scale factor like
-xscale 0.5halves the width and leaves the height alone, since factors work independently unless you say otherwise. - Want both dimensions scaled the same: use a single positional factor such as
0.5, or set both-xscaleand-yscaleexplicitly. The positional form still works for compatibility, but named options are easier to audit later.
5. Reduce by a pixel budget
Use -pixels when a downstream limit cares about total pixel count rather than a particular width. It scales down to no more than the requested number of pixels and keeps the aspect ratio:
$ pamscale -pixels 1000000 /path/to/source.ppm > preview.ppm
$ pamfile preview.ppm
preview.ppm: PPM raw, 1154 by 866
The example output is illustrative for a suitably large source; check your own result with pamfile. An input already below the limit gets copied rather than enlarged, which makes -pixels a good maximum-size rule but a poor way to guarantee a specific thumbnail size.
6. Pick the sampling behaviour deliberately
By default pamscale mixes pixels, which usually gives smoother reductions and can create new intermediate colours. Add -nomix for discrete sampling instead: it keeps samples from the source palette but can make thin lines uneven or vanish during reduction.
$ pamscale -nomix -width 200 /path/to/source.ppm > palette-safe.ppm
$ pamfile palette-safe.ppm
palette-safe.ppm: PPM raw, 200 by 150
This matters most for palette-limited workflows: mixing may need a later colour-quantisation step before conversion to a restricted format. Discrete sampling isn't automatically higher quality, it's just what you want when preserving exact source values beats smooth averaging.
For finer control, -filter=function selects a resampling filter, with names such as box, triangle, sinc and lanczos. A filter still needs a scale selection alongside it:
$ pamscale -width 800 -filter=box /path/to/source.ppm > filtered.ppm
Tip
Don't combine -linear with -filter: the installed manpage says -linear is unavailable for resampling and pamscale will fail outright. With the default mixing method, -linear is for samples that are already proportional to light intensity. Ordinary PNM and PAM samples are normally gamma-adjusted, so leave it off unless your data format specifically justifies it.
Common traps
- PBM input, unexpected PGM output. pamscale normally keeps the input's image type, but a PBM input becomes PGM with maxval 255 so pixel mixing has meaningful intermediate values. Convert back explicitly with
pamditherbw, or considerpbmreduce, if you need PBM again. - Multi-image streams. pamscale scales each image in the stream independently on this Netpbm version. That behaviour changed after Netpbm 10.49, so check the package version on any older installation before relying on it.
- Unusual PAM tuple types. Anything outside RGB, grayscale, black-and-white and their alpha variants has no defined general result.
- Command fails outright. Check the input is readable, every option has a value, and the output directory is writable. Add
-verbosefor scaling messages on standard error, and keep diagnostics separate from standard output, which is the image stream, not text.
Done means
- Versions checked. You confirmed the installed pamscale and Netpbm versions.
- Size previewed. You used
-reportonlywhen the exact dimensions mattered. - Output verified. You wrote to a new destination and checked its dimensions with
pamfile. - Sampling justified. You chose pixel mixing,
-nomixor a named filter for a reason you could state out loud. - Edge cases covered. You accounted for PBM conversion, pixel budgets and multi-image input where any applied.