PNG to PPM / PGM / PBM
Netpbm is the format you reach for when you want pixels with almost no format in the way — a three-line text header followed by raw bytes. It is what university assignments ask for, what a lot of C and Rust image code reads first, and what you write out when you want to inspect a file by eye in a text editor.
Drop images here
PNG, JPG, WebP, GIF — multiple files allowed
Which of the six you want
The family splits two ways. PPM is colour, PGM is greyscale and PBM is one bit per pixel; and each of those comes in a binary form (P6, P5, P4) and an ASCII form (P3, P2, P1) that spells every value out as decimal text. Binary is what you want for anything real — the ASCII variants are three to four times larger and exist so you can open the file and read the numbers.
For coursework, read the assignment carefully: "PPM" almost always means P6, but a surprising
number of exercises specifically want P3 so that a marker can diff the file. If you are feeding
a C parser you wrote yourself, P6 is the one worth supporting first — the header is
P6, whitespace, width, whitespace, height, whitespace, 255, a single
whitespace byte, then width × height × 3 bytes in row-major order with no padding and no
per-row prefix.
Note that Netpbm has no alpha channel at all in any of its six variants. Transparent pixels are composited onto the colour you pick above before anything is written, so a logo on a transparent background becomes a logo on white unless you say otherwise. The threshold only matters for the PBM outputs, where every pixel has to end up either fully black or fully white — anything darker than the threshold becomes an ink bit.
The comment line
Every file written here carries one # comment line after the magic number. That is
legal everywhere in the header per the specification, and most parsers skip comments correctly,
but a hand-rolled parser that assumes the header is exactly three tokens will trip over it. If
you are debugging a reader of your own and the dimensions come out as garbage, the comment line
is the first thing to check — a correct parser has to skip from a # to the next
newline anywhere whitespace is allowed.
FAQ
What's the difference between PPM and PNM?
PNM isn't a seventh format — it is the umbrella name for all six, and the .pnm extension means "one of these, look at the magic number to find out which". Tools that accept PNM accept PPM, PGM and PBM alike.
Can I get 16-bit output?
No — this writes maxval 255, which is one byte per sample. Netpbm does allow a maxval up to 65535 with two big-endian bytes per sample, but a browser canvas only gives 8 bits per channel to begin with, so 16-bit output would be padding rather than precision.
How do I convert back?
Not here yet. pnmtopng from the Netpbm suite, ImageMagick's convert, or a three-line Python script with Pillow will all do it. The format is simple enough that reading it is a genuinely reasonable exercise.
Why is my ASCII PPM enormous?
Because every channel of every pixel is written as up to three decimal digits plus a separator. A 1000×1000 image is three million numbers. That is the format working as intended; use P6 if you want the same pixels in a quarter of the space.