1

I'm looking for a way to save (efficiently if possible) two 2D numpy arrays into one plain ppm image. I think the only difference between standard (raw) and plain ppm image is than the latter limits line length to 70 chars.

The only way I can think of is to save each array to separate colour channels. Say first array as Red, second as Green, and leave Blue at 0? Though not sure does it make sense...

Ideally the ppm file will by 'human readable' (not a data buffer). I know that scipy can save it as raw ppm (but not human readable)

Any ideas welcome

ad1v7
  • 187
  • 1
  • 12
  • You say you have two 2D arrays, and you want "one plain ppm image". Do you mean one ppm *file* that contains two images, or do you really want to combine the two arrays to create one image? – Warren Weckesser Oct 28 '17 at 17:42
  • One plain ppm file to represent data from two arrays. Yes, i should have been more specific. Say R channel is for first array G channel for second array and B set at constant? Not really sure would it work that's way I asked the question – ad1v7 Oct 28 '17 at 17:43
  • Also note that, according to [this description of the PPM format](http://netpbm.sourceforge.net/doc/ppm.html), a *plain* PPM file (with "magic number" P3 instead of P6) can contain only one image. – Warren Weckesser Oct 28 '17 at 17:44
  • Yes that is correct but see previous comment – ad1v7 Oct 28 '17 at 17:46
  • Please put the information from that comment into the question itself. Without it, the question is incomplete. – Warren Weckesser Oct 28 '17 at 17:49

1 Answers1

3

The plain PPM format is so simple that it would probably take you only a few minutes to write the code to create one. If you'd rather use an existing library, you can use imageio if you also install the freeimage backend. Then you can do something like the following.

Suppose a and b are the two arrays.

In [100]: a
Out[100]: 
array([[36, 19, 60, 73],
       [ 2, 27, 13, 22],
       [19, 50, 38, 18],
       [47, 69, 55, 52]], dtype=uint8)

In [101]: b
Out[101]: 
array([[221, 252, 236, 225],
       [248, 254, 226, 248],
       [221, 232, 216, 208],
       [207, 243, 249, 231]], dtype=uint8)

Create a 3-D array, and copy a and b into it.

In [102]: data = np.zeros(a.shape + (3,), dtype=a.dtype)

In [103]: data[:,:,0] = a

In [104]: data[:,:,1] = b

Use imageio.imwrite to create the PPM file. Use the format PPM-FI to use the freeimage backend, and set flags=1 to create a plain PPM file (i.e. ASCII, not raw).

In [105]: import imageio

In [106]: imageio.imwrite('data.ppm', data, format='PPM-FI', flags=1)

Here's the file:

In [107]: !cat data.ppm
P3
4 4
255
 36 221   0  19 252   0  60 236   0  73 225   0   2 248   0 
 27 254   0  13 226   0  22 248   0  19 221   0  50 232   0 
 38 216   0  18 208   0  47 207   0  69 243   0  55 249   0 
 52 231   0 
Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214