16 ответов:
можно использовать PyPNG. Это чистый Python (без зависимостей) с открытым исходным кодом PNG-кодер / декодер, и это поддерживает запись массивов NumPy в виде изображений.
Это использует PIL, но, возможно, некоторые могут найти его полезным:
import scipy.misc scipy.misc.imsave('outfile.jpg', image_array)EDIT: текущая
scipyверсия начала нормализовать все изображения, чтобы min(данные) стали черными, а max (данные) стали белыми. Это нежелательно, если данные должны быть точными серыми уровнями или точными каналами RGB. Решение:import scipy.misc scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
Pure Python (2 & 3), фрагмент без сторонних зависимостей.
эта функция записывает сжатый, истинный цвет (4 байта на пиксель)
RGBAPNG.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'')])... Данные должны быть записаны непосредственно в файл, открытый как двоичный, например:
data = write_png(buf, 64, 64) with open("my_image.png", 'wb') as fd: fd.write(data)
- первоисточник
- Читайте также: порт ржавчины от этого вопроса.
- пример использования благодаря @Evgeni Sergeev: https://stackoverflow.com/a/21034111/432509
С
matplotlib:import matplotlib matplotlib.image.imsave('name.png', array)работает с matplotlib 1.3.1, я не знаю о более низкой версии. Из строки документа:
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.
здесь
opencvдля 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)))полезно, если вам нужно сделать больше обработки, кроме спасения.
добавление к ответу @ideasman42:
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)<<8)|(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()так что вы можете сделать:
saveAsPNG([[0xffFF0000, 0xffFFFF00], [0xff00aa77, 0xff333333]], 'test_grid.png')производства
test_grid.png:
(прозрачность также работает, уменьшая старший байт от
0xff.)
вы можете использовать библиотеку 'skimage' в Python
пример:
from skimage.io import imsave imsave('Path_to_your_folder/File_name.jpg',your_array)
matplotlib svn имеет новую функцию для сохранения изображений как просто изображение - без осей и т. д. это очень простая функция для резервного копирования, если вы не хотите устанавливать svn (скопированный прямо из image.py в matplotlib svn удалена строка документа для краткости):
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)
миру, вероятно, не нужен еще один пакет для записи массива numpy в файл PNG, но для тех, кто не может получить достаточно, я недавно поставил
numpngwна github:https://github.com/WarrenWeckesser/numpngw
и на pypi: https://pypi.python.org/pypi/numpngw/
единственная внешняя зависимость-numpy.
вот первый пример от
examplesкаталог репозитория. Этот существенная линия простоwrite_png('example1.png', img)здесь
img- это массив numpy. Весь код перед этой строкой-это операторы импорта и код для создания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)вот файл PNG, который он создает:
предполагая, что вы хотите получить изображение в оттенках серого:
im = Image.new('L', (width, height)) im.putdata(an_array.flatten().tolist()) im.save("image.tiff")
Если вам случится, чтобы использовать уже [Пы]Qt, вы можете быть заинтересованы в qimage2ndarray. Начиная с версии 1.4 (только что выпустили), PySide также поддерживается, и будет маленькая
imsave(filename, array)функции, схожие с scipy, но с использованием Qt, а не пил. С 1.3, просто используйте что-то вроде следующего:qImage = array2qimage(image, normalize = False) # create QImage from ndarray success = qImage.save(filename) # use Qt's image IO functions for saving PNG/JPG/..(еще одним преимуществом 1.4 является то, что это чистое решение python, что делает его еще более легким.)
Если вы работаете в среде python Spyder, то это не может быть проще, чем просто щелкнуть правой кнопкой мыши массив в обозревателе переменных, а затем выбрать опцию Показать изображение.
Это попросит вас сохранить изображение в dsik, в основном в формате PNG.
библиотека PIL в этом случае не понадобится.
scipy.miscдает предупреждение об устареванииimsaveфункция и предлагает использование .import imageio imageio.imwrite('image_name.png', img)
использовать
cv2.imwrite.import cv2 assert mat.shape[2] == 1 or mat.shape[2] == 3, 'the third dim should be channel' cv2.imwrite(path, mat) # note the form of data should be height - width - channel





Comments