Convert Unknown Image Files to PNM with anytopnm
anytopnm looks at an image file it does not recognise, works out what it actually is, and turns it into a Netpbm image you can pipe anywhere. It writes PBM, PGM or PPM to standard output, so the "conversion" is really just shell redirection into a new file. Give it about ten minutes for your first run. You need the netpbm package and a readable input file.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide describes Netpbm 11.5.2, installed here as Debian package version 2:11.05.02-1.1build1. The manual page is dated 15 November 2014, so check the installed documentation if your package differs substantially.
1. Check the installed command
Confirm the shell runs the binary you expect and note the package version. These are read-only checks, no sudo needed:
$ command -v anytopnm
/usr/bin/anytopnm
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
$ anytopnm -version
pamtopnm: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
...
The version output pulls in Netpbm library details and possibly build information too. What matters is that it names the Netpbm release you expect.
Checkpoint
You have a working /usr/bin/anytopnm and know which package version you are testing.
2. Convert a file to a new output
Replace /path/to/input-image with your image's path. The destination name below is just an example, not a fixed output format: pick an extension that matches what you expect back, then check it actually matches:
$ anytopnm /path/to/input-image > converted.pnm
$ file converted.pnm
converted.pnm: Netpbm image data, size = 640 x 480, pixmap, rawbits, binary
The exact file description depends on your input. The converter picks PBM, PGM or PPM from the image data itself; there is no separate output-format flag, and it never resizes anything.
Do not point this at a file you care about without a safety net first. Shell > truncates an existing destination before anytopnm even starts, so a bad run costs you the old file too. Write to a temporary name instead, and only rename it in once you have confirmed the conversion worked:
$ anytopnm /path/to/input-image > converted.pnm.new
$ test -s converted.pnm.new
$ file converted.pnm.new
$ mv -- converted.pnm.new converted.pnm
That final mv is the only step that touches the real destination. If an earlier command fails, leave the original alone and go investigate. Recovering from an accidental overwrite means pulling the file back from backup: anytopnm has no undo.
3. Use standard input in a pipeline
Pass -, or leave the filename out entirely, when the image arrives on standard input, for example from another command or a source with no useful filename:
$ cat /path/to/input-image | anytopnm - > converted.pnm
$ file converted.pnm
converted.pnm: Netpbm image data, size = 640 x 480, pixmap, rawbits, binary
anytopnm still has to work out what it is looking at: first via file, possibly helped by Netpbm's magic-number data, then by falling back to the filename extension. A stream piped in has no extension, so a format that cannot be spotted from its contents will fail here. When that happens, reach for the format-specific converter instead, such as giftopnm for GIF.
In a script, do not trust the output file alone: make a pipeline failure visible.
$ set -o pipefail
$ producer-command | anytopnm - > converted.pnm
$ printf 'pipeline status: %s\n' "$?"
pipeline status: 0
Swap in a real command for producer-command. Do not pipe an untrusted string straight into a shell.
4. Let anytopnm handle compressed input
If file spots Unix compress, gzip or bzip compression, anytopnm decompresses the input before it even picks a converter, and hands you back plain, uncompressed PNM:
$ anytopnm /path/to/input-image.gz > converted.pnm
$ file converted.pnm
converted.pnm: Netpbm image data, size = 640 x 480, pixmap, rawbits, binary
That is not a blanket guarantee for every compressed or encoded format: the wrapper still needs a Netpbm converter for whatever image format is underneath. The manual also covers uuencode and btoa input when file can identify it.
5. Check multiple-image behaviour
Some formats pack several images into one file. Usually you get a multi-image Netpbm stream back, but the manual is upfront that some converters keep only the first frame. GIF is the version-sensitive case: Netpbm 10.69 and later convert every image in a multi-image GIF, older releases convert only the first.
A clean exit status does not mean every frame survived. If you have a Netpbm inspection tool installed, use it, and test a real animated or multi-page file before trusting this in an archive pipeline. The netpbm package ships pamfile, though exactly what it reports depends on the output and the tool version:
$ pamfile converted.pnm
converted.pnm: Netpbm image data, size = 640 x 480, pixmap, rawbits, binary
6. Diagnose a failed conversion
anytopnm has no conversion-specific flags of its own, and it does not accept the usual libnetpbm options either, apart from -version. If it cannot place the input, or the format converter it needs is missing, read the error and try the format-specific tool by hand. Check the input independently first:
$ file /path/to/input-image
/path/to/input-image: PNG image data, 640 x 480, 8-bit/color RGB, non-interlaced
$ anytopnm /path/to/input-image > converted.pnm
$ printf 'status: %s\n' "$?"
status: 0
A non-zero status means the conversion did not finish cleanly: treat any partial output as unusable and remove or quarantine it before you retry. Deleting a generated file is a one-way trip, so check the path carefully before you run rm. Ordinary reading and writing in your own directory needs no elevated privileges; if permissions get in the way, fix access on the specific input or destination rather than running the whole thing as root.
Done means
anytopnm -versionand the package query identify the installed Netpbm release.- The converted file was written to a deliberate destination and checked with
file. - You know PBM, PGM or PPM output is chosen from the input, not by an anytopnm flag.
- Compressed input and standard-input pipelines are only used where format detection stays reliable.
- Existing output is protected from shell-redirection truncation, and a failed conversion is never treated as a valid image.
- Multi-image input has been checked wherever preserving every frame matters.