The basics
What is a PNM file?
PNM stands for Portable Anymap, a name for a small family of image formats that belong to Netpbm, an open-source toolkit for converting and editing images on the command line. Each format stores a picture as plainly as possible: a few lines of text saying how big the image is, then every pixel, uncompressed.
The formats go back to Jef Poskanzer, who designed PBM in the 1980s so that pictures could be sent inside plain-text email. In 1988 he released Pbmplus, a set of converters between PBM and other formats, and added PGM and PPM the same year. Netpbm replaced Pbmplus in 1993 and is still maintained; Bryan Henderson has looked after it since 1999. The PAM format arrived in August 2000.
- PBM (
.pbm): black and white, one bit per pixel. - PGM (
.pgm): greyscale. - PPM (
.ppm): colour, red, green and blue per pixel. - PAM (
.pam): any number of channels, for example RGB plus alpha. - PNM (
.pnm): not a separate format, but the name for "PBM, PGM or PPM, whichever it is". Programs that accept PNM read all three.
Netpbm's own manual calls PPM a "lowest common denominator" format: it carries almost no metadata and wastes space, but any program can read or write it. That makes PNM a common go-between in image pipelines and a favourite in teaching, where students can write an image file in a few lines of code without a library.
Anatomy
What's inside a PNM file
A Netpbm file is a magic number, the width and height, the maximum sample value, and then the pixels. Here is a complete plain PPM file, written for this page: a 3 × 2 image with six coloured pixels. You can type it into a text editor, save it as tiny.ppm, and open it in GIMP. Below it is the same image as a raw PPM, byte by byte.
P3
# 99helpers example: 3 x 2 pixels
3 2
255
255 0 0 0 255 0 0 0 255
255 255 0 255 255 255 0 0 0
The same image as raw PPM (P6), all 29 bytes:
50 36 0A 33 20 32 0A 32 35 35 0A
FF 00 00 00 FF 00 00 00 FF
FF FF 00 FF FF FF 00 00 00- 1
P3The magic number
Two ASCII characters that say which format follows.
P3is a colour image with pixels written as decimal numbers in text (plain PPM). The other numbers are listed in the table further down. - 2
# 99helpers example: 3 x 2 pixelsA comment
Anything from
#to the end of the line is a comment. Comments are allowed in the header, before the pixels; tools ignore them, and many drop them when they convert the file. - 3
3 2Width and height
3 pixels wide, 2 rows high, as decimal numbers separated by whitespace. Spaces, tabs and line breaks all count as whitespace, so
3 2could be split over two lines. - 4
255Maxval
The largest value a sample can have, from 1 to 65,535. 255 means one byte per sample in a raw file; above 255, each sample takes two bytes, most significant byte first. PBM has no maxval: a pixel is just 0 or 1.
- 5
255 0 0 0 255 0 0 0 255The first row
Three numbers per pixel: red, green, blue. This row is red, green and blue. Rows go from top to bottom, pixels from left to right. The spacing is only for reading: the format needs at least one whitespace character between numbers, and lines should stay under 70 characters.
- 6
255 255 0 255 255 255 0 0 0The second row
Yellow, white and black. Nothing marks the end of a row or of the file: a reader knows from the width and height how many numbers to expect.
- 7
50 36 0A 33 20 32 0A 32 35 35 0AThe raw header
The raw version starts with the same kind of header in ASCII:
P6, a newline (0A),3 2, a newline,255, and exactly one whitespace character. After that single byte, the pixels begin. - 8
FF 00 00 00 FF 00 …Raw pixels
Each sample is one byte:
FF 00 00is red. 18 bytes for 6 pixels, no padding, no compression and no checksum. That's why PNM files are large but trivial to read and write: a program can produce one with aprintfand a loop.
Variants
The magic numbers P1 to P7
The first two bytes of a Netpbm file say exactly what it is. Each of the three classic formats has a plain variant, with pixels written as decimal text, and a raw variant, with pixels in binary. Netpbm programs write raw files unless you ask for plain ones with -plain.
| Magic | Format | Pixels | Extension |
|---|---|---|---|
P1 | Plain PBM | 0 and 1 as text; 1 is black | .pbm |
P2 | Plain PGM | Grey values as decimal text | .pgm |
P3 | Plain PPM | Red, green, blue as decimal text | .ppm |
P4 | Raw PBM | 8 pixels per byte, most significant bit first; each row padded to a whole byte | .pbm |
P5 | Raw PGM | 1 byte per pixel, or 2 if maxval is over 255 | .pgm |
P6 | Raw PPM | 3 or 6 bytes per pixel | .ppm |
P7 | PAM | Binary only; a header of named fields and any number of channels | .pam |
Black is 1, or 0
In PBM, 1 means black and 0 white: ink on paper. In PGM and PPM, 0 is black and maxval is white: light on a screen. PAM's black-and-white type follows the second rule, so its manual warns that the same bit means opposite things in PBM and PAM.
A PAM header uses names instead of positions, which makes it easy to extend:
P7
WIDTH 227
HEIGHT 149
DEPTH 3
MAXVAL 255
TUPLTYPE RGB
ENDHDRTUPLTYPE names the meaning of the channels: BLACKANDWHITE, GRAYSCALE, RGB, or the same with _ALPHA added, where the last channel is opacity. Older tools that only know PNM can't read PAM, and the P7 magic number is also used by xv thumbnails, an unrelated format.
Under the hood
Plain or raw: text pixels or binary pixels
Both variants share the same header. The difference is only in the pixels:
| Plain (P1, P2, P3) | Raw (P4, P5, P6) | |
|---|---|---|
| Pixels | Decimal numbers separated by whitespace | Binary bytes, straight after one whitespace character |
| Size | About 3 to 4 times larger for 8-bit images, since each sample is up to 3 digits plus a space | Exactly width × height × bytes per pixel, plus the header |
| Readable in a text editor | Yes | Only the header |
| Safe in email and copy-paste | Yes | No: it's binary |
| Several images in one file | No | Yes: images can follow one another with nothing in between (since July 2000) |
Raw files are what tools normally write and expect. Plain files are for people: for debugging, for tests you can read in a diff, and for exercises where students write the pixels themselves. Readers are asked to be generous with plain files, so extra spaces and line breaks don't matter.
PPM's manual says the samples are gamma-encoded with the ITU-R BT.709 curve, but adds that many programs write sRGB or linear values instead. In practice, treat an 8-bit PPM like any other 8-bit RGB image. Because there's no colour profile field, the file can't tell you which it is.
PFM, the floating-point cousin
A PFM (Portable Float Map) file looks similar but stores 32-bit floating-point samples. It starts with PF for colour or Pf for greyscale. It's not one of the PNM formats, but Netpbm and Pillow can convert it, and it's used for HDR images.
Comparison
PNM vs PNG, BMP and TIFF
| PNM | PNG | BMP | TIFF | |
|---|---|---|---|---|
| Compression | None | Lossless (DEFLATE) | Usually none | None, lossless or lossy |
| Header | A few lines of ASCII | Binary chunks with CRCs | Binary, fixed layout | Binary tags |
| Transparency | Only in PAM | Full alpha | Possible, rarely supported | Yes |
| Metadata | Comments only | Text, Exif, colour profiles | Colour profiles | Extensive |
| Opens in a browser | No | Yes | Yes | Only Safari |
| Best for | Pipelines, tests, teaching | Sharing graphics | Windows software | Archives, print, science |
Use PNM inside a pipeline, between tools, or when you need a format you can write without a library. Use PNG to keep or share the result: it's lossless too, much smaller, and opens everywhere. BMP is the nearest Windows equivalent; TIFF is the choice when metadata, 16-bit colour and compression all matter.
In practice
Where you'll meet PNM files
- Command-line conversion. Netpbm has hundreds of programs, most named after what they convert:
pngtopam,pnmtopng,jpegtopnm,pnmscale. Each reads PNM, does one thing and writes PNM, so they chain with pipes:jpegtopnm photo.jpg | pnmscale 0.5 | pnmtopng > small.png. - Document tools. Some programs write Netpbm by default. Poppler's
pdftoppmrenders PDF pages to PPM unless told otherwise, and DjVuLibre'sddjvucan write PNM, as on our DjVu page. - Teaching and research. Image-processing courses use PPM and PGM because a student can write a blur filter or a ray tracer and save the result with a few
printfcalls. - Tests and fixtures. A plain PNM file is a readable, diffable test image: the expected output of a filter can sit in a repository as text.
- Old Unix software and fax tools, where Netpbm was the standard way to move images between programs.
How to
How to open and convert a PNM file
- On Windows: the built-in Photos app doesn't support Netpbm files. Use GIMP or IrfanView, or convert the file first.
- On macOS: GIMP opens all four formats; so do ImageMagick and the Netpbm tools, installed with Homebrew or MacPorts.
- On Linux: most image viewers read PNM, and the Netpbm tools are in every distribution's packages (usually
netpbm). - In a browser: no browser displays PNM. Convert it to PNG first.
- With ImageMagick:
magick input.ppm output.png, or the other way round. Add-compress noneto write a plain (P1, P2, P3) file. - With Netpbm:
pnmtopng input.ppm > output.png,pngtopam input.png > output.pam, orpnmtopnm -plain input.ppm > plain.ppmto turn a raw file into a plain one. - In Python: Pillow reads and writes PBM, PGM and PPM:
Image.open("input.ppm").save("output.png"). It doesn't support PAM.
Since there's no compression, PNM files get big fast: a 12-megapixel photo as raw PPM is 36 MB, and about three times that as plain PPM. Convert to PNG for storage, or compress with gzip or xz if you need to keep the PNM.
Troubleshooting
Common PNM problems
- The image is skewed or shifted diagonally. The reader is out of step with the bytes, usually because a raw file was opened in text mode on Windows (which changes line endings) or because a writer put two whitespace characters after maxval instead of one.
- Colours are garbled in a 16-bit file. Two-byte samples are big-endian. A program that writes them little-endian, as the computer stores them in memory, produces noise. Swap the bytes or use a library.
- A PBM comes out inverted. In PBM, 1 is black. Code that treats 1 as white (as in PGM, or in PAM's black-and-white type) produces a negative.
- A program says "bad magic number". It may be a PAM (
P7) file and the program only reads PNM, or a PFM (PF), or not a Netpbm file at all. Look at the first two bytes. - Only the first image is read. Raw files can hold several images in a row, but most programs stop after the first.
Security
Is a PNM file safe?
A PNM file holds pixels and comments, nothing that runs. The risks are in the programs that read it:
- Huge dimensions. A header of a few bytes can claim an image of 100,000 × 100,000 pixels. A reader that allocates memory before checking the file length can be pushed into using gigabytes. Check width × height against a limit before decoding.
- Short files. A truncated raw file has fewer bytes than the header promises. Hand-written readers must check, not assume, how much data arrived.
- Comments travel with the file. They can contain a user name, a path or a command line. They're easy to miss and easy to strip: converting the file usually removes them.
Sample files
There are no sample PNM files on this page yet. The 3 × 2 example in the anatomy is a complete PPM: copy it into a text editor and save it as tiny.ppm, or make one from any image with ImageMagick (magick input.png output.ppm) or Netpbm (pngtopam input.png > output.pam).
Put it online
Have a PNM file? Give it a link.
Drop a PBM, PGM, PPM or PAM file on 99helpers and it gets its own web address. Browsers can't display Netpbm images, so anyone who opens the link downloads the file; to have the picture seen in the browser, upload a PNG copy next to it.
Questions
PNM files, frequently asked
What is a .pnm file?
An image in one of the Netpbm formats: PBM (black and white), PGM (greyscale) or PPM (colour). The .pnm extension is used when it doesn't matter which. The file is a short text header followed by uncompressed pixels.
What's the difference between PBM, PGM, PPM and PNM?
PBM stores 1 bit per pixel, PGM a grey value per pixel, PPM red, green and blue per pixel. PNM is the collective name for the three, and PAM is a newer, more general format that can also hold transparency.
How do I open a PPM file on Windows?
Windows' Photos app doesn't support it. Use GIMP or IrfanView, or convert it with ImageMagick (magick input.ppm output.png).
What's the difference between P3 and P6?
Both are PPM colour images. P3 (plain) writes each sample as a decimal number in text; P6 (raw) stores samples as binary bytes. P6 is smaller and is what tools normally write; P3 can be read and edited in a text editor.
Are PPM files compressed?
No. Every pixel is stored in full, so a raw 1920 × 1080 PPM is about 6.2 MB. Compress it with gzip or convert it to PNG to save space without losing anything.
Can a PPM have transparency?
No. PBM, PGM and PPM have no alpha channel. Use PAM with the RGB_ALPHA tuple type, or PNG.
How do I write a PPM file from my own code?
Write P6, a newline, the width and height, a newline, 255 and a newline, then 3 bytes (red, green, blue) for each pixel, row by row from the top. Open the file in binary mode.
Related formats
Other file types explained
Keep going
Related
Sources
- Netpbm: PPM format specification (manual page)
- Netpbm: PBM format specification (manual page)
- Netpbm: PGM format specification (manual page)
- Netpbm: PAM format specification (manual page)
- Netpbm: history of Netpbm
Last reviewed 27 October 2026.