Каков самый быстрый способ рисовать изображение из дискретных значений пикселей в Python?
Я хочу нарисовать изображение, основанное на вычисленных значениях пикселей, как средство визуализации некоторых данных. По сути, я хочу взять 2-мерную матрицу цветовых триплетов и визуализировать ее.
Обратите внимание, что это не обработка изображений, так как я не преобразовываю существующее изображение и не делаю никаких преобразований целого изображения, а также не векторную графику, поскольку нет предопределенной структуры для изображения я ' m rendering - я, вероятно, собираюсь производить аморфные капли цвета по одному пикселю за раз.
Мне нужно отображать изображения примерно на 1kx1k пикселей, но что-то масштабируемое было бы полезно. Конечным целевым форматом является PNG или любой другой формат без потерь.
Я использовал PIL в данный момент с помощью ImageDraw draw.point, и мне было интересно, учитывая специфические и относительно основные функции, которые мне нужны, есть ли более быстрая библиотека?
Ответы
Ответ 1
Если у вас есть numpy
и scipy
(и если вы манипулируете большими массивами в Python, я бы порекомендовал их), то функция scipy.misc.pilutil.toimage
очень удобна. Простой пример:
import numpy as np
import scipy.misc as smp
# Create a 1024x1024x3 array of 8 bit unsigned integers
data = np.zeros( (1024,1024,3), dtype=np.uint8 )
data[512,512] = [254,0,0] # Makes the middle pixel red
data[512,513] = [0,0,255] # Makes the next pixel blue
img = smp.toimage( data ) # Create a PIL image
img.show() # View in default viewer
Приятно то, что toimage
справляются с разными типами данных, поэтому двумерный массив чисел с плавающей точкой разумно преобразуется в оттенки серого и т.д.
Вы можете скачать numpy
и scipy
от сюда. Или используя пункт:
pip install numpy scipy
Ответ 2
import Image
im= Image.new('RGB', (1024, 1024))
im.putdata([(255,0,0), (0,255,0), (0,0,255)])
im.save('test.png')
Помещает красный, зеленый и синий пиксели в верхнем левом углу изображения.
im.fromstring()
быстрее, если вы предпочитаете иметь дело с байтовыми значениями.
Ответ 3
Требования
Для этого примера установите Numpy и Pillow.
пример
Цель состоит в том, чтобы сначала представить изображение, которое вы хотите создать, в виде массива массивов наборов из 3 (RGB) чисел - используйте Numpy array()
, для производительности и простоты:
import numpy
data = numpy.zeros((1024, 1024, 3), dtype=numpy.uint8)
Теперь установите значения RGB средних 3 пикселей на красный, зеленый и синий:
data[512, 511] = [255, 0, 0]
data[512, 512] = [0, 255, 0]
data[512, 513] = [0, 0, 255]
Затем с помощью Pillow Image.fromarray()
сгенерируйте изображение из массива:
from PIL import Image
image = Image.fromarray(data)
Теперь "покажите" изображение (в OS X это откроет его как временный файл в Preview):
image.show()
Заметка
Этот ответ был вдохновлен ответом BADCODE, который слишком устарел для использования и слишком отличается от простого обновления без полной перезаписи.
Ответ 4
Другой подход заключается в использовании Pyxel, реализации API TIC-80 с открытым исходным кодом в Python3 (TIC-80 - это PICO-8 с открытым исходным кодом).
Вот полное приложение, которое просто рисует один желтый пиксель на черном фоне:
import pyxel
def update():
"""This function just maps the Q key to 'pyxel.quit',
which works just like 'sys.exit'."""
if pyxel.btnp(pyxel.KEY_Q): pyxel.quit()
def draw():
"""This function clears the screen and draws a single
pixel, whenever the buffer needs updating. Note that
colors are specified as palette indexes (0-15)."""
pyxel.cls(0) # clear screen (color)
pyxel.pix(10, 10, 10) # blit a pixel (x, y, color)
pyxel.init(160, 120) # initilize gui (width, height)
pyxel.run(update, draw) # run the game (*callbacks)
Примечание. Библиотека допускает использование не более шестнадцати цветов, но вы можете выбрать, какие цвета, и, возможно, вы сможете получить больше поддержки без особой работы.
Ответ 5
Я думаю, вы используете PIL для создания файла образа на диске, а позже загрузите его с помощью программного обеспечения для чтения изображений.
Вы должны получить небольшое улучшение скорости, непосредственно отображая изображение в памяти (вы сэкономите стоимость записи изображения на диск, а затем перезагрузите его). Посмотрите на эту тему https://stackoverflow.com/info/326300/python-best-library-for-drawing, чтобы отобразить это изображение с помощью различных модулей python.
Я лично попробую wxpython и функцию dc.DrawBitmap. Если вы используете такой модуль, а не внешний читатель изображений, у вас будет много преимуществ:
- скорость
- вы сможете создать интерактивный пользовательский интерфейс с кнопками параметров.
- вы сможете легко запрограммировать функцию Zoomin и Zoomout
- вы сможете построить изображение по мере его вычисления, что может быть весьма полезно, если вычисление занимает много времени.