Ответ 1
Вы можете использовать PyPNG. Это чистый Python (без зависимостей) open source PNG encoder/decoder и поддерживает запись массивов NumPy в виде изображений.
У меня есть матрица в типе массива Numpy. Как записать его на диск как образ? Работает любой формат (png, jpeg, bmp...). Одним из важных ограничений является то, что PIL отсутствует.
Вы можете использовать PyPNG. Это чистый Python (без зависимостей) open source PNG encoder/decoder и поддерживает запись массивов NumPy в виде изображений.
В этом случае используется PIL, но, возможно, некоторые из них могут оказаться полезными:
import scipy.misc
scipy.misc.imsave('outfile.jpg', image_array)
EDIT. Текущая версия scipy
начала нормализовать все изображения, чтобы мин (данные) стали черными, а макс (данные) стали белыми. Это нежелательно, если данные должны быть точными уровнями серого или точными каналами RGB. Решение:
import scipy.misc
scipy.misc.toimage(image_array, cmin=0.0, cmax=...).save('outfile.jpg')
Ответ с использованием PIL (на всякий случай это полезно).
для массива numpy "A":
from PIL import Image
im = Image.fromarray(A)
im.save("your_file.jpeg")
вы можете заменить "jpeg" практически любым желаемым форматом. Подробнее о форматах здесь
Pure Python (2 и 3), фрагмент без сторонних зависимостей.
Эта функция записывает сжатые PNG- RGBA
формате true color (4 байта на пиксель).
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)
С matplotlib
:
import matplotlib
matplotlib.image.imsave('name.png', array)
Работает с matplotlib 1.3.1, я не знаю о более низкой версии. Из документа 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.
Если у вас есть matplotlib, вы можете сделать:
import matplotlib.pyplot as plt
plt.imshow(matrix) #Needs to be in row,col order
plt.savefig(filename)
Там 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)))
полезно, если вам нужно сделать больше обработки, кроме сохранения.
Добавление к ответу @ideaman42:
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)
scipy.misc
выдает предупреждение об imsave
функции imsave
и предлагает вместо этого использовать imageio
.
import imageio
imageio.imwrite('image_name.png', img)
В мире, вероятно, не нужен еще один пакет для записи массива 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")
Если вы уже используете [Py] Qt, вас может заинтересовать qimage2ndarray. Начиная с версии 1.4 (только что выпущенной) поддерживается PySide, и будет крошечная функция imsave(filename, array)
, похожая на scipy's, но используя Qt вместо PIL. С 1.3 просто используйте что-то вроде следующего:
qImage = array2qimage(image, normalize = False) # create QImage from ndarray
success = qImage.save(filename) # use Qt image IO functions for saving PNG/JPG/..
(Еще одно преимущество 1.4 заключается в том, что это чистое решение python, что делает его еще более легким.)
Для тех, кто ищет прямой полностью рабочий пример:
from PIL import Image
import numpy
w,h = 200,100
img = numpy.zeros((h,w,3),dtype=numpy.uint8) # has to be unsigned bytes
img[:] = (0,0,255) # fill blue
x,y = 40,20
img[y:y+30, x:x+50] = (255,0,0) # 50x30 red box
Image.fromarray(img).convert("RGB").save("art.png") # don't need to convert
Кроме того, если вы хотите высокое качество JPEG .save(file, subsampling=0, quality=100)
Если вы работаете в среде Python Spyder, то это не может быть проще, чем просто щелкнуть правой кнопкой мыши массив в проводнике переменных, а затем выбрать параметр Показать изображение.
Это попросит вас сохранить изображение в dsik, в основном в формате PNG.
Библиотека PIL в этом случае не понадобится.
Используйте 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
Imageio - это библиотека Python, которая обеспечивает простой интерфейс для чтения и записи широкого спектра данных изображений, включая анимированные изображения, видео, объемные данные и научные форматы. Он кроссплатформенный, работает на Python 2.7 и 3. 4+ и прост в установке.
Это пример для изображения в градациях серого:
import numpy as np
import imageio
# data is numpy array with grayscale value for each pixel.
data = np.array([70,80,82,72,58,58,60,63,54,58,60,48,89,115,121,119])
# 16 pixels can be converted into square of 4x4 or 2x8 or 8x2
data = data.reshape((4, 4)).astype('uint8')
# save image
imageio.imwrite('pic.jpg', data)