在Python中从离散像素值绘制图像的最快方法是什么?

问题描述 投票:33回答:5

我希望基于计算的像素值绘制图像,作为可视化某些数据的手段。基本上,我希望采用二维矩阵颜色三元组并渲染它。

请注意,这不是图像处理,因为我没有变换现有图像,也没有进行任何形式的全图像变换,而且它也不是矢量图形,因为我正在渲染的图像没有预先确定的结构 - 我可能会一次生成一个像素的无定形色块。

我现在需要渲染大约1kx1k像素的图像,但是可扩展的东西会很有用。最终目标格式是PNG或任何其他无损格式。

我一直在通过ImageDraw的draw.point使用PIL,我想知道,鉴于我需要的非常具体和相对基本的功能,是否有更快的库可用?

python image python-imaging-library
5个回答
33
投票

如果你有numpyscipy可用(如果你在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可以很好地处理不同的数据类型,因此浮点数的2D数组可以合理地转换为灰度等。

你可以从numpy下载scipyhere。或者使用pip:

pip install numpy scipy

16
投票
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()会更快。


2
投票

Requirements

在本例中,安装NumpyPillow

Example

我们的目标是首先将您想要创建的图像表示为3(RGB)数字组的数组 - 使用Numpy的array(),以获得性能和简单性:

import numpy

data = numpy.zeros((1024, 1024, 3), dtype=numpy.uint8)

现在,将中间3像素的RGB值设置为红色,绿色和蓝色:

data[512, 511] = [255, 0, 0]
data[512, 512] = [0, 255, 0]
data[512, 513] = [0, 0, 255]

然后,使用Pillow的Image.fromarray()从数组生成一个Image:

from PIL import Image

image = Image.fromarray(data)

现在,“显示”图像(在OS X上,这将在预览中将其作为临时文件打开):

image.show()

Note

这个答案的灵感来自于BADCODE的答案,这个答案太过于过时而且太过不同,只是在没有完全重写的情况下更新。


2
投票

另一种方法是使用Pyxel,这是Python3中the TIC-80 API的开源实现(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)

注意:该库最多只允许16种颜色,但您可以更改哪种颜色,并且您可以在不需要太多工作的情况下获得更多颜色。


1
投票

我认为您使用PIL在磁盘上生成图像文件,然后使用图像读取器软件加载它。

通过直接在内存中渲染图片,您可以获得较小的速度提升(您将节省在磁盘上写入图像然后重新加载它的成本)。看看这个线程https://stackoverflow.com/questions/326300/python-best-library-for-drawing如何使用各种python模块渲染该图像。

我个人会尝试wxpython和dc.DrawBitmap函数。如果您使用这样的模块而不是外部图像阅读器,您将获得许多好处:

  • 速度
  • 您将能够使用参数按钮创建交互式用户界面。
  • 您将能够轻松编程Zoomin和Zoomout功能
  • 您可以在计算图像时绘制图像,如果计算需要花费大量时间,这将非常有用
© www.soinside.com 2019 - 2024. All rights reserved.