Convert a PGM Image to Dithered Black and White with pamditherbw
You will finish with a black-and-white PAM image made from a greyscale PGM, using a dither method you can name and repeat. The installed command is from Netpbm 11.5.2, packaged here as 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 ten minutes. You need Netpbm's pamditherbw and pamfile commands, plus a PGM or greyscale PAM input. The examples write new files in the current directory and do not require elevated privileges. They do not alter the input.
1. Check the input and installed version
Start by checking the command that will run and the package version. These are read-only checks:
$ command -v pamditherbw
/usr/bin/pamditherbw
$ pamditherbw --version
pamditherbw: 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 version diagnostic includes build details after the first line. If your output reports another version, read its local manual page before relying on version-specific details. The -randomseed option used below was added in Netpbm 10.45.
Checkpoint: inspect the input before converting it. This catches a colour file or a damaged header without creating output:
$ pamfile input.pgm
input.pgm: PGM, 1920 by 1080 by 255
Replace input.pgm with the path to your file. The command expects PGM or PAM with tuple type GRAYSCALE. It does not validate that promise: with a PPM colour image it takes the first channel as though it were grey, so the result may be arbitrary. Do not use a colour file by accident.
2. Run the default Floyd-Steinberg conversion
The default is boustrophedonic Floyd-Steinberg error diffusion. Send the PAM result to a new file with shell redirection:
$ pamditherbw -fs input.pgm > output.pam
-fs is an alias for -floyd. With no method option, the command uses the same Floyd-Steinberg default. The output is PAM with tuple type BLACKANDWHITE, not legacy PBM. Verify the file before passing it to another program:
$ pamfile output.pam
output.pam: PAM, 1920 by 1080 by 1 maxval 1
Tuple type: BLACKANDWHITE
Your dimensions will differ. If the command reports an input error, check the path and header first. If you see a permissions error, choose a directory you can write to. Do not solve a local output permission problem with sudo unless the destination is deliberately privileged.
3. Make a repeatable result
Floyd-Steinberg and Atkinson use random numbers while diffusing error. By default the seed is based on the time and process ID, so two runs can differ. Supply an integer seed when a build, test or comparison needs the same result:
$ pamditherbw -fs -randomseed=123 input.pgm > output-123.pam
$ pamditherbw -fs -randomseed=123 input.pgm > output-123-again.pam
$ cmp output-123.pam output-123-again.pam
# no output from cmp means the files match
The seed option is written with an equals sign, followed by an integer. It has no effect for methods that do not use random numbers. Keep the seed in a script or build log when reproducibility matters.
4. Choose a different visual treatment
Change the quantisation method only when the output's character or downstream use calls for it. The practical choices are:
-thresholdmakes a simple brightness cut. It is useful before image-processing tasks such as edge or peak detection, but it can look harsh.-atkinsonis another error-diffusion method and often gives a good-looking result.-dither8, also-d8, uses a 16 by 16 Bayer ordered-dither matrix.-cluster3,-cluster4and-cluster8, with aliases-c3,-c4and-c8, create different clustered-dot patterns with a newspaper-like appearance.-hilbertuses a Hilbert-curve halftoning method, which can suit devices that do not render individual pixels distinctly.
For example, compare thresholding with Atkinson output without overwriting the first result:
$ pamditherbw -threshold input.pgm > threshold.pam
$ pamditherbw -atkinson -randomseed=123 input.pgm > atkinson.pam
$ pamfile threshold.pam atkinson.pam
The command accepts unique abbreviated options, but full names are easier to review in scripts and less likely to become ambiguous if options change.
5. Tune the threshold or Hilbert clump
-value changes the thresholding value for Floyd-Steinberg, Atkinson and simple thresholding. It must be between 0 and 1. Values above 0.5 produce darker images; values below 0.5 produce lighter images:
$ pamditherbw -threshold -value 0.4 input.pgm > lighter.pam
$ pamditherbw -threshold -value 0.6 input.pgm > darker.pam
Do not confuse -value with a general brightness correction. It changes the threshold used by those three methods, not the source image.
For Hilbert dithering, -clump changes the number of pixels in a clump. The usual range is 2 to 100 and the default is 5. Smaller values smear the image less and appear less grainy, but can reduce greyscale linearity:
$ pamditherbw -hilbert -clump 2 input.pgm > hilbert-small.pam
$ pamfile hilbert-small.pam
Use this as a visual or printer-specific adjustment, not as a universal quality setting. An out-of-range value may be accepted differently by another Netpbm build, so stay within the documented range.
6. Convert to PBM only when an older tool needs it
Keep the PAM output if the next program understands PAM. If an older program requires PBM, convert the validated result with pamtopnm:
$ pamtopnm output-123.pam > output.pbm
$ pamfile output.pbm
output.pbm: PBM, 1920 by 1080
This conversion creates another file and leaves both PAM and PBM available. If the downstream program can consume PAM, skipping this step avoids an unnecessary format conversion.
7. Recover from a bad output or failed run
The examples are non-destructive to the input, but shell redirection replaces an existing destination before the program writes. Before re-running a command, choose a new filename or confirm that the old output is disposable. If the output is wrong, remove it using your normal file-management process or restore it from your backup. There is no image-editing undo inside pamditherbw.
A non-zero exit status or a missing output normally means a bad path, unreadable input, invalid image data or an unwritable destination. Re-run with a new output path after checking those conditions. A successful pamfile check confirms the container and tuple type, not that the visual result is suitable for your purpose.
Done means
- The installed Netpbm version and input type are known.
- The source is PGM or greyscale PAM, not an unverified colour image.
- A selected dither method produced PAM with tuple type
BLACKANDWHITE. - A fixed seed was used where byte-for-byte repeatability matters.
-valueor-clumpwas used only for the method it affects.- PBM conversion was done only when the next tool requires it.