Home / Alt manpages / pamtopng(1)

  • pamtopng(1)
  • User command
  • linux

Convert PAM Images to PNG Without Losing Transparency

Convert a PAM image to PNG with pamtopng and the alpha channel survives, which is the whole reason this tool exists instead of the older pnmtopng. Expect about ten minutes to convert, check maxval, preserve transparency and set metadata deliberately.

The examples were checked against Netpbm package version 2:11.05.02-1.1build1, whose installed pamtopng accepts PBM, PGM, PPM and PAM input. You need a shell, pamtopng and a readable input image, nothing here needs root or a service restart. Every example writes a new file, so pick an output path you control and do not overwrite an original until the result has been checked.

1. Check the installed tool

Confirm the command and package match what you expect:

$ command -v pamtopng
/usr/bin/pamtopng
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1

The manpage is your real interface reference here. It allows minimum unique option abbreviation, double hyphens, and whitespace instead of an equals sign. Stick to full option names in scripts anyway, since abbreviations can silently become ambiguous after an upgrade.

Checkpoint: confirm the input is actually Netpbm data before converting it:

$ pamfile /path/to/input.pam
/path/to/input.pam: PAM ...

Whatever comes after the colon depends on the file. Another Netpbm type reported here is still perfectly valid input. If it is not Netpbm data at all, run it through the right importer first rather than guessing from the header.

2. Convert a normal image to PNG

Filename last, redirect standard output to a new PNG:

$ pamtopng /path/to/input.pam > /path/to/output.png
$ file /path/to/output.png
/path/to/output.png: PNG image data, ...

Leave out the filename and pamtopng reads standard input instead, which drops it straight into a pipeline:

$ pamfile /path/to/input.ppm
$ pamtopng < /path/to/input.ppm > /path/to/output.png
$ identify /path/to/output.png
/path/to/output.png PNG ...

Never point > at the original file. The shell truncates the destination before the converter reads a byte of it, so that can destroy your source outright. A failed conversion means inspecting the error and writing to a fresh temporary or recovery path, not retrying against an already-damaged original.

3. Check maxval before troubleshooting PNG output

pamtopng only accepts input maxval values of 1, 3, 15, 255 and 65535. Anything else gets rejected outright. Check the header with pamfile; for a PAM file, the MAXVAL line is also visible with an ordinary read-only command:

$ sed -n '1,12p' /path/to/input.pam
P7
WIDTH 640
HEIGHT 480
DEPTH 4
MAXVAL 255
TUPLTYPE RGB_ALPHA
ENDHDR

Unsupported maxval? Normalise a copy with pamdepth, then feed the copy to pamtopng:

$ pamdepth 255 /path/to/input.pam > /tmp/input-255.pam
$ pamtopng /tmp/input-255.pam > /tmp/output.png
$ file /tmp/output.png
/tmp/output.png: PNG image data, ...

That only changes the sample precision in the copy, never the source. Write into /tmp or another directory with enough space, and clean up temporary files according to your own retention policy.

When conversion involves scaling, PNG colour components get written at 8 or 16 bits, and pamtopng records the original bit depth in an sBIT chunk. That metadata describes what happened; it is not a licence to skip normalising an unsupported maxval first.

4. Preserve a PAM alpha channel

This is the whole point of pamtopng over pnmtopng: a PAM with tuple type RGB_ALPHA becomes a PNG with a real alpha channel. Confirm it with an image inspector:

$ pamtopng /path/to/rgba.pam > /tmp/rgba.png
$ file /tmp/rgba.png
/tmp/rgba.png: PNG image data, ..., 8-bit/color RGBA, non-interlaced
$ identify -verbose /tmp/rgba.png | grep -E 'Type:|Alpha:'
  Type: TrueColorAlpha
    Alpha:

Exact dimensions, byte counts and the verbose alpha stats will vary with your input. What matters is that the output reports RGBA or otherwise shows an alpha channel. A plain PPM has no alpha to begin with, so converting one cannot conjure transparency that was never there.

pamtopng always writes a colour PNG from a colour PAM, even if every pixel happens to be grey. Want a smaller, genuinely greyscale PNG? Convert to a greyscale Netpbm type first with the relevant Netpbm tool, and check that doing so does not throw away transparency you actually need.

5. Add colour and transparency metadata deliberately

  • -transparent: makes every pixel of one exact colour fully transparent, using Netpbm colour syntax.
  • -background=white: writes a background colour chunk for later transparency conversions; it is metadata for consumers, not a command that flattens the image.
  • -gamma=.45: records the usual Netpbm gamma information for true PPM or PGM input; use a different value only if the source genuinely uses another transfer function.
  • -srgbintent: takes perceptual, relativecolorimetric, saturation or absolutecolorimetric, and records an sRGB rendering intent.
$ pamtopng -transparent=rgb:ff/00/0d input.ppm > output-transparent.png
$ identify -verbose output-transparent.png | grep -E 'Type:|Alpha:'
  Type: PaletteAlpha
    Alpha:

Unlike some behaviour associated with pnmtopng, pamtopng will not substitute a nearby colour when the exact one you asked for is not present. If the result looks unchanged, check the image's actual samples rather than the command line.

The -chroma value packs eight numbers, in the order white, red, green and blue, each as a CIE-1931 X and Y chromaticity pair. Quote it so the shell treats it as one argument:

$ pamtopng -chroma='0.3127 0.3290 0.6400 0.3300 0.3000 0.6000 0.1500 0.0600' input.ppm > output-colour.png

Those numbers are an example of the syntax, not a universal calibration you should copy elsewhere. Use the values that actually apply to your source.

6. Choose interlace and metadata files with care

-interlace writes Adam7 interlacing, which can help progressive display over a slow connection, but it also forces pamtopng to hold the entire image in memory instead of one row at a time. Leave it off for large images unless progressive display is a genuine requirement; it was added in Netpbm 10.86, so it is present in this build.

PNG text chunks come from files, not arbitrary extra words on the command line. -text=FILE writes uncompressed tEXt chunks, -ztxt=FILE writes compressed zTXt chunks, and -itxt=FILE writes iTXt entries with language and translated-key fields. The file format is line-oriented: an entry starts in column one, continuation lines start with whitespace, and the key always comes first.

$ cat > /tmp/png-text.txt <<'EOF'
Title PNG conversion test
Description
 A PNG made from a PAM image
EOF
$ pamtopng -text=/tmp/png-text.txt input.pam > output-with-text.png
$ identify -verbose output-with-text.png | grep -A2 -i 'properties:'

The here-document only writes a temporary metadata file. Read it back before embedding anything: PNG metadata travels far too easily and can disclose names, paths or internal project details you did not mean to ship.

Done means

  • Version confirmed: pamtopng and its Netpbm package version are checked.
  • Source intact: the original file is untouched and the new one is recognised as PNG.
  • Maxval handled: the input maxval was already supported, or a copy was normalised with pamdepth.
  • Transparency verified: a PAM alpha channel or exact transparent colour was checked in the output.
  • Metadata deliberate: colour metadata and interlacing were chosen for this source, not copied blindly.
  • Nothing leaked: temporary files and embedded metadata contain nothing that should not travel with the image.