48

我希望根据计算的像素值绘制图像,作为可视化某些数据的一种方式。本质上,我希望获取一个二维矩阵的颜色三元组并渲染它。

请注意,这不是图像处理,因为我没有转换现有图像,也没有进行任何形式的整体图像转换,它也不是矢量图,因为我正在渲染的图像没有预先确定的结构-我可能会一次产生一个像素的无定形颜色斑点。

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

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

4

6 回答 6

38

如果您有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地处理不同的数据类型,因此浮点数的 2D 数组可以明智地转换为灰度等。

您可以从这里下载numpy和。或使用点子:scipy

pip install numpy scipy
于 2009-01-12T16:20:57.640 回答
21
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()如果您更喜欢处理字节值,则速度更快。

于 2009-01-12T11:57:48.857 回答
7

要求

对于这个例子,安装NumpyPillow

例子

目标是首先将您要创建的图像表示为 3 个 (RGB) 数字集的数组数组 - 使用 Numpy's 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]

然后,使用 PillowImage.fromarray()从数组中生成图像:

from PIL import Image

image = Image.fromarray(data)

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

image.show()

笔记

这个答案的灵感来自 BADCODE 的答案,它太过时了,无法使用,也太不同了,无法在不完全重写的情况下简单地更新。

于 2018-01-24T20:11:45.050 回答
2

另一种方法是使用Pyxel ,这是 Python3中 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 种颜色,但您可以更改哪些颜色,并且您可能无需太多工作就可以支持更多颜色。

于 2018-07-30T23:58:13.947 回答
1

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

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

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

  • 速度
  • 您将能够创建带有参数按钮的交互式用户界面。
  • 您将能够轻松地对 Zoomin 和 Zoomout 功能进行编程
  • 您将能够在计算时绘制图像,如果计算需要大量时间,这将非常有用
于 2009-01-12T08:35:27.130 回答
0

turtle如果您不想安装外部模块,可以使用该模块。我创建了一些有用的功能:

  • setwindowsize( x,y )- 将窗口大小设置为 x*y
  • drawpixel( x, y, (r,g,b), pixelsize)- 使用 RGB 颜色(元组)将像素绘制到 x:y 坐标,具有像素大小的厚度
  • showimage()- 显示图像
import turtle

def setwindowsize(x=640, y=640):
    turtle.setup(x, y)
    turtle.setworldcoordinates(0,0,x,y)

def drawpixel(x, y, color, pixelsize = 1 ):
    turtle.tracer(0, 0)
    turtle.colormode(255)
    turtle.penup()
    turtle.setpos(x*pixelsize,y*pixelsize)
    turtle.color(color)
    turtle.pendown()
    turtle.begin_fill()
    for i in range(4):
        turtle.forward(pixelsize)
        turtle.right(90)
    turtle.end_fill()

def showimage():
    turtle.hideturtle()
    turtle.update()

例子:

200x200 窗口,中心 1 个红色像素

setwindowsize(200, 200)
drawpixel(100, 100, (255,0,0) )
showimage()

在此处输入图像描述

30x30 随机颜色。像素大小:10

from random import *

setwindowsize(300,300)

for x in range(30):
    for y in range(30):
        color = (randint(0,255),randint(0,255),randint(0,255))
        drawpixel(x,y,color,10)
    
showimage()

在此处输入图像描述

于 2021-02-28T05:05:17.357 回答