Monday, May 05, 2014

Le format image PNM / PNM easy graphic format

PNM (Portable aNy Map) is a graphic file format by Jef Poskanzer (b. 1958) in the eighties.

Such graphic files can have more specific extensions:

.pbm (Portable BitMap) for black/white graphics files

.pgm (Portable GrayMap) for grays graphics files (it can be more than 50)

.ppm (Portable PixMap) for coloured graphic files

It's no compressed format, and even worse (a single pixel can be encoded '243 222 123 '!), but very easy to create. A PNM begins with a tag ('P1' to 'P6'), a width, a height and (for gray files and coloured maps) a hightest value; after comes the data.

The P1, P2 and P3 data are ascii-coded and space-separated. A comment is possible between an # and an end-of-line before the dimensions; the P4, P5 and P6 data are binary-coded, with no separation.

P1: black&white ascii-coded image

A PNM Black/White file begins with 'P1 width height ' (width and height are pixel values), followed by '0' (white) or '1' (black), and - if you want - a space between each pixel.

P1 6 4
1 1 1 1 1 1
1 0 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

"P1 6 4 111111100001100001111111 " is an equivalent (a last dummy pixels seems to be necessary).

Note: this graphic is a 6x4 pixels images, you'll have to zoom it.

A 1000x1000 pixels will be 1 or 2MB large, but it's possible to shrink it by 8 (each pixel is a bit) with the P4 binary format (see below).

P2: gray ascii-coded image

These files begins with 'P2' tag,
a width and a height, followed by the highest value (until 255). The data are also ascii-typed and must have space-separations. In the following sample the values go from 0 (black) to 6
(white)

P2 4 4 6
6 5 4 3
5 4 3 2
4 3 2 1
3 2 1 0

"P2 4 4 6 6 5 4 3 5 4 3 2 4 3 2 1 3 2 1 0 " is an equivalent.

P3: coloured ascii-coded image

A coloured graphic ASCII begins with a 'P3' tag, follow by a width, a height and a maximal value. The datas are a sequence of three values which are the red, green and blue values:

The number of spaces betwen each value doesn't have any importance. Red, green and blue are only coded with 0 or 255: in this example, it's possible to code in an easier way, setting the maximal value to 1 (before the '#'):

P4, P5 et P6: binary formats

P4, P5 et P6 tags in the beginning of a PNM file are respectivily for black/white, gray scaled and coloured graphics where values are binary coded:

P4: black & white binary-coded:

P4 16 16
...byte-coded data

...without space nor carriage-return ('\n','\r')

For a P4-PNM file, the first eight pixels must be translated into a value between 0 ('00000000') and 255 ('11111111').

For instance, WBBWWBBW is encoded through the binary number '01100110' = 102, (the 'f' character).

You can translate the binary number with int(number,2), and transform it into a character with char():

char(int("01100110",2))

The file will be:

"P4 8 4
ffff"

Some values cannot be written with ASCII-character. You can use chr(int('001100110',2) in a routine.

The best should be adding a line in your script with a command which transforms a PNM-file into PNG-one with os.system("convert image.pnm image.png") from the ImageMagick package (Unix only?).

P5 gray binary-coded image: each pixels is coded by a byte.

P6 colour binary-coded image: each pixel is coded by three bytes (red/green/blue)

How to generate a P1-file

This script generates a black circle on a white background (you give the radius). It tests the pixels one by one: are they at the good distance from the center (x°,y°)? Pythagore answers with r²=(x-x°)²+(y-y°)². A file 'circle'+diameter+'.pnm' is created.

Add comment

Add comment

Your name

Enter single word term described on the image

Search

About The Author

Sociologist specialized in credences, I like scriptings and I find python is a rather good replacement for Omikron BASIC (8:), which unfortunately doesn't exist on Linux (and Atari doesn't exist anymore, though FireBee does exist).

All scripts are here written on GNU/Linux/Debian/Python 2.x, I'm not sure it's easy to adapt them in a Windows or Mac environment.

I write french pages about python: www.jchr.be/python, and some more on www.jchr.be (in french, since I'm a french-speaking Belgian)