Enlarge Netpbm Images with pamenlarge
pamenlarge scales a Netpbm image by an exact integer factor, duplicating pixels as it goes. The result stays deliberately blocky unless you add a smoothing step afterwards. This guide covers whole-image and single-axis scaling, safe pipelines, safe replacement of an existing file, and the PBM speed quirk worth knowing about. Allow about ten minutes for a first conversion.
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 PBM, PGM, PPM or PAM image. This guide was tested with Netpbm 11.5.2, package version 2:11.05.02-1.1build1; other releases may differ, especially around the newer option syntax.
1. Check the installed command
$ command -v pamenlarge
/usr/bin/pamenlarge
$ pamenlarge --version
pamenlarge: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
...
$ man pamenlarge
pamenlarge has no detailed --help screen, so the manual page is the real interface reference. The current syntax is pamenlarge -scale=INTEGER FILE; the older positional form pamenlarge INTEGER FILE still works.
2. Enlarge both dimensions
Pick a new destination first. Shell redirection with > truncates an existing file before pamenlarge even starts, so never point it at an output you might need to recover:
$ pamenlarge -scale=2 /path/to/input.pgm > /path/to/input-2x.pgm
$ file /path/to/input-2x.pgm
/path/to/input-2x.pgm: Netpbm image data, size 2N x 2M, rawbits, greymap
Swap in real paths. The displayed dimensions are placeholders: a source that is N pixels wide and M high becomes 2N by 2M. Output stays the same Netpbm image type as the input, though a text PGM can come out as raw PGM, so do not judge the image type from encoding alone.
Checkpoint
Confirm the destination exists, is non-empty and has the expected width and height. No file command available? Check the Netpbm header with pamfile instead.
3. Scale only one axis
Use -xscale for horizontal enlargement and -yscale for vertical. Specify only one and the other axis gets a factor of 1:
$ pamenlarge -xscale=3 /path/to/input.pgm > /path/to/input-wide.pgm
$ file /path/to/input-wide.pgm
/path/to/input-wide.pgm: Netpbm image data, size 3N x M, rawbits, greymap
$ pamenlarge -yscale=2 /path/to/input.pgm > /path/to/input-tall.pgm
$ file /path/to/input-tall.pgm
/path/to/input-tall.pgm: Netpbm image data, size N x 2M, rawbits, greymap
Pass both for independent factors:
$ pamenlarge -xscale=3 -yscale=2 /path/to/input.pgm > /path/to/input-3x2.pgm
Do not combine -scale with either axis-specific option: the program rejects that outright because it describes the same dimension twice.
4. Use standard input in a pipeline
The input file is optional. With none, or with -, pamenlarge reads the image from standard input and writes the enlarged image to standard output:
$ cat /path/to/input.pgm | pamenlarge -scale=2 > /path/to/pipeline-output.pgm
$ file /path/to/pipeline-output.pgm
/path/to/pipeline-output.pgm: Netpbm image data, size 2N x 2M, rawbits, greymap
In a longer pipeline, keep the output redirection at the very end or hand off to another Netpbm program: a failure earlier in the chain can otherwise leave a partial or misleading destination. For scripts, check the exit status and use a temporary name before replacing a trusted output.
5. Replace an existing output safely
Updating an existing image changes state and can still discard the old one, so keep a backup until the new dimensions and appearance are confirmed:
$ cp --preserve=all /path/to/output.pgm /path/to/output.pgm.bak
$ pamenlarge -scale=2 /path/to/input.pgm > /path/to/output.pgm.new
$ file /path/to/output.pgm.new
/path/to/output.pgm.new: Netpbm image data, size 2N x 2M, rawbits, greymap
$ mv /path/to/output.pgm.new /path/to/output.pgm
If conversion fails, the original output.pgm and its backup remain: remove the incomplete .new file after checking it. Once the replacement is confirmed, deleting the backup is your call to make and irreversible once made. Nothing here needs sudo unless your chosen directories deny your normal user access.
6. Diagnose a rejected scale factor
Scale factors must be positive integers; zero or negative is not a request to shrink the image:
$ pamenlarge -scale=0 /path/to/input.pgm > /tmp/not-created.pgm
pamenlarge: -scale must be positive. You specified zero
$ printf 'exit status: %s\n' "$?"
exit status: 1
The exact wording can vary, but a non-zero status means the conversion failed. Do not treat a file created by redirection as proof of success: the shell can create or truncate it before the program even reports an error. For unattended work, use a temporary destination and remove it only after a successful status and a dimension check.
pamenlarge only handles integer enlargement. Reach for pamscale for arbitrary enlargement or reduction with resampling, or pamstretch for integer enlargement with simple smoothing. For a factor of 3 or more, the manual itself suggests considering pnmsmooth because duplicated pixels stay visible.
7. Pick a practical factor for PBM images
PBM input has an implementation detail worth knowing: Netpbm has a fast path for PBM scale factors up to 10 and a slower, simpler path above that. For a factor of 15, two passes can beat one:
$ pamenlarge -scale=5 /path/to/input.pbm | pamenlarge -scale=3 > /path/to/input-15x.pbm
$ file /path/to/input-15x.pbm
/path/to/input-15x.pbm: Netpbm image data, size 15N x 15M, rawbits, bitmap
Order can affect speed even though both give the same dimensions and pixel values. This is an optimisation for large PBM jobs, not a requirement for ordinary images, so measure your own inputs before adding a multi-pass pipeline to a batch.
Done means
- Version checked. pamenlarge is installed and its Netpbm version is known.
- Input verified. The source is readable and the chosen factor is a positive integer.
- Dimensions match the horizontal and vertical factors you asked for.
- Source protected. The original is untouched, and important destinations are shielded from accidental truncation.
- Smoothing considered. Pixel duplication keeps hard edges, and a separate smoothing tool was used when that mattered.