I have a matrix in the type of a Numpy array. How would I write it to disk it as an image? Any format works (png, jpeg, bmp...). One important constraint is that PIL is not present.
问题:
回答1:
You can use PyPNG. It's a pure Python (no dependencies) open source PNG encoder/decoder and it supports writing NumPy arrays as images.
回答2:
This uses PIL, but maybe some might find it useful:
import scipy.misc scipy.misc.imsave('outfile.jpg', image_array)
EDIT: The current scipy
version started to normalize all images so that min(data) become black and max(data) become white. This is unwanted if the data should be exact grey levels or exact RGB channels. The solution:
import scipy.misc scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
回答3:
An answer using PIL (just in case it's useful).
given a numpy array "A":
from PIL import Image im = Image.fromarray(A) im.save("your_file.jpeg")
you can replace "jpeg" with almost any format you want. More details about the formats here
回答4:
Pure Python (2 & 3), a snippet without 3rd party dependencies.
This function writes compressed, true-color (4 bytes per pixel) RGBA
PNG's.
def write_png(buf, width, height): """ buf: must be bytes or a bytearray in Python3.x, a regular string in Python2.x. """ import zlib, struct # reverse the vertical line order and add null bytes at the start width_byte_4 = width * 4 raw_data = b''.join( b'\x00' + buf[span:span + width_byte_4] for span in range((height - 1) * width_byte_4, -1, - width_byte_4) ) def png_pack(png_tag, data): chunk_head = png_tag + data return (struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))) return b''.join([ b'\x89PNG\r\n\x1a\n', png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)), png_pack(b'IDAT', zlib.compress(raw_data, 9)), png_pack(b'IEND', b'')])
... The data should be written directly to a file opened as binary, as in:
data = write_png(buf, 64, 64) with open("my_image.png", 'wb') as fd: fd.write(data)
- Original source
- See also: Rust Port from this question.
- Example usage thanks to @Evgeni Sergeev: https://stackoverflow.com/a/21034111/432509
回答5:
With matplotlib
:
import matplotlib matplotlib.image.imsave('name.png', array)
Works with matplotlib 1.3.1, I don't know about lower version. From the docstring:
Arguments: *fname*: A string containing a path to a filename, or a Python file-like object. If *format* is *None* and *fname* is a string, the output format is deduced from the extension of the filename. *arr*: An MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA) array.
回答6:
If you have matplotlib, you can do:
import matplotlib.pyplot as plt plt.imshow(matrix) #Needs to be in row,col order plt.savefig(filename)
回答7:
There's opencv
for python (http://docs.opencv.org/trunk/doc/py_tutorials/py_tutorials.html).
import cv2 import numpy as np cv2.imwrite("filename.png", np.zeros((10,10)))
useful if you need to do more processing other than saving.
回答8:
Addendum to @ideasman42's answer:
def saveAsPNG(array, filename): import struct if any([len(row) != len(array[0]) for row in array]): raise ValueError, "Array should have elements of equal size" #First row becomes top row of image. flat = []; map(flat.extend, reversed(array)) #Big-endian, unsigned 32-byte integer. buf = b''.join([struct.pack('>I', ((0xffFFff & i32)>24) ) for i32 in flat]) #Rotate from ARGB to RGBA. data = write_png(buf, len(array[0]), len(array)) f = open(filename, 'wb') f.write(data) f.close()
So you can do:
saveAsPNG([[0xffFF0000, 0xffFFFF00], [0xff00aa77, 0xff333333]], 'test_grid.png')
Producing test_grid.png
:

(Transparency also works, by reducing the high byte from 0xff
.)
回答9:
matplotlib svn has a new function to save images as just an image -- no axes etc. it's a very simple function to backport too, if you don't want to install svn (copied straight from image.py in matplotlib svn, removed the docstring for brevity):
def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, origin=None): from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from matplotlib.figure import Figure fig = Figure(figsize=arr.shape[::-1], dpi=1, frameon=False) canvas = FigureCanvas(fig) fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin) fig.savefig(fname, dpi=1, format=format)
回答10:
The world probably doesn't need yet another package for writing a numpy array to a PNG file, but for those who can't get enough, I recently put up numpngw
on github:
https://github.com/WarrenWeckesser/numpngw
and on pypi: https://pypi.python.org/pypi/numpngw/
The only external dependency is numpy.
Here's the first example from the examples
directory of the repository. The essential line is simply
write_png('example1.png', img)
where img
is a numpy array. All the code before that line is import statements and code to create img
.
import numpy as np from numpngw import write_png # Example 1 # # Create an 8-bit RGB image. img = np.zeros((80, 128, 3), dtype=np.uint8) grad = np.linspace(0, 255, img.shape[1]) img[:16, :, :] = 127 img[16:32, :, 0] = grad img[32:48, :, 1] = grad[::-1] img[48:64, :, 2] = grad img[64:, :, :] = 127 write_png('example1.png', img)
Here's the PNG file that it creates:
回答11:
If you happen to use [Py]Qt already, you may be interested in qimage2ndarray. Starting with version 1.4 (just released), PySide is supported as well, and there will be a tiny imsave(filename, array)
function similar to scipy's, but using Qt instead of PIL. With 1.3, just use something like the following:
qImage = array2qimage(image, normalize = False) # create QImage from ndarray success = qImage.save(filename) # use Qt's image IO functions for saving PNG/JPG/..
(Another advantage of 1.4 is that it is a pure python solution, which makes this even more lightweight.)
回答12:
Assuming you want a grayscale image:
im = Image.new('L', (width, height)) im.putdata(an_array.flatten().tolist()) im.save("image.tiff")
回答13:
You can use 'skimage' library in Python
Example:
from skimage.io import imsave imsave('Path_to_your_folder/File_name.jpg',your_array)