17

I found my answer in a previous post: Saving a Numpy array as an image. The only problem being, there isn't much instruction on using the PyPNG module.

There are only a few examples online-- http://packages.python.org/pypng/ex.html#numpy http://nullege.com/codes/search/png.Writer.write

But what do I do in light of .write errors like this:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/png.py", line 638, in write
    nrows = self.write_passes(outfile, rows)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/png.py", line 783, in write_passes
    extend(row)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/png.py", line 780, in <lambda>
    return lambda sl: f(map(int, sl))
TypeError: argument 2 to map() must support iteration

Here's where the error happens in my code, PCA_tool.py (The error comes after "folder.write(outfilename, PrincipalComponent"):

#PrincipalComponent.save(path+'transform_'+str(each)+'.png', format='PNG')
outfilename = open(str(path)+'transformed/transform_'+str(each)+'.png', 'wb')
folder = png.Writer(m,n,greyscale=True)
folder.write(outfilename, PrincipalComponent)
outfilename.close()

sys.exit(0)

I'm trying to save a 8400 element numpy.ndarray as a n=80 column, m=105 row greyscale png image.

Thanks,

Community
  • 1
  • 1
Alvin
  • 357
  • 1
  • 3
  • 11
  • 2
    PIL, for all it's problems, is at least more widely used, and therefore a bit better supported. http://www.pythonware.com/products/pil/ You'd probably be better off just doing any rescaling you need to (e.g. rescale and convert to `uint8`) and then `Image.fromarray(data).save('whatever.png')` – Joe Kington Aug 02 '11 at 16:16
  • I should say, PrincipalComponent is of numpy.ndarray type and not a list. I can rescale the array using PrincipalComponent.reshape(row,col), but conversion of a numpy.ndarray into a writable image file? – Alvin Aug 02 '11 at 18:43
  • That's (a `numpy.ndarray`) what `Image.fromarray` expects, for what it's worth. – Joe Kington Aug 02 '11 at 18:57

3 Answers3

40

You might be better off using PIL:

from PIL import Image
import numpy as np

data = np.random.random((100,100))

#Rescale to 0-255 and convert to uint8
rescaled = (255.0 / data.max() * (data - data.min())).astype(np.uint8)

im = Image.fromarray(rescaled)
im.save('test.png')
Pouyan
  • 363
  • 5
  • 22
Joe Kington
  • 275,208
  • 71
  • 604
  • 463
0
import matplotlib.pyplot as plt
import numpy as np
plt.imshow(np.random.random(100, 100))
plt.savefig('')
Rob
  • 26,989
  • 16
  • 82
  • 98
  • 3
    Hello, consider adding an explanation of your code. – tima Aug 29 '17 at 13:51
  • 1
    Welcome to Stack Overflow! Thank you for this code snippet, which may provide some immediate help. A proper explanation [would greatly improve](//meta.stackexchange.com/q/114762) its educational value by showing *why* this is a good solution to the problem, and would make it more useful to future readers with similar, but not identical, questions. Please [edit] your answer to add explanation, and give an indication of what limitations and assumptions apply. – Toby Speight Aug 29 '17 at 15:48
  • 2
    this doesn't work as expected as it include the matplotlib frame – yota Mar 03 '20 at 21:59
-1

It would be best to use scipy for it.

from scipy.misc import imsave
# x is the array you want to save 
imsave("image.png", x)

Full documentation is here: https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.misc.imsave.html

killmenow
  • 1
  • 1