pngtoolskit.org
PNG and image utilities, in the browser
Say hi →

PNG to PPM / PGM / PBM

P6 · P5 · P4 binary · P3 · P2 · P1 ASCII · batch

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

    no files
    Ready.

    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.