如何使用PIL绘制函数生成的值?

问题描述 投票:0回答:2

我想知道如何在间隔(-1,1)中使用python中的PIL绘制任何函数。我已经开始使用函数y = x**2,到目前为止我有这个:

from PIL import Image

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)


def parabola(x):
    return (-1) * (x ** 2)

def draw_function(function, size=200):
    im = Image.new("RGB", (size, size))
    for x in range(size):
        for y in range(size):
            if function(x)< function(y):
                im.putpixel((x,y), BLACK)
            else:
                im.putpixel((x,y), WHITE)
    im.show()

draw_function(parabola)

但我得到的只是:

enter image description here

我想得到:

enter image description here

你能告诉我问题出在哪里吗?

python image python-imaging-library
2个回答
2
投票

好吧,我不认为你正确地解决了这个问题。首先,考虑一下像素为黑色的条件意味着:

function(x) < function(y)

这并没有真正定义抛物线下面的区域。这样做的条件是

function(x) < y

另外,想想你的绘图区域是什么。这是[0, 200) x [0, 200)。此外,在PIL中,x坐标在图像中向下增加,因此您的抛物线将是可见的(如果有的话)颠倒。

这是对您的代码的一点修改:

from PIL import Image

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)


def parabola(x):
    return (-1) * ((x - 100) ** 2) + 150

def draw_function(function, size=200):
    im = Image.new("RGB", (size, size))
    for x in range(size):
        for y in range(size):
            if function(x) < y:
                im.putpixel((x,y), BLACK)
            else:
                im.putpixel((x,y), WHITE)
    im.show()

draw_function(parabola)

这应该产生一个有点像这样的图片:enter image description here


0
投票

您需要确保xy值,以便它们代表0size-1范围内的坐标,以便使用它们在Image上绘制。这是在下面的代码中完成的,首先找到函数将为该范围内的x值返回的最小值和最大值。然后它使用它们来翻译(移动)并缩放它们,使它们都落入所需的范围。要使曲线下方的区域为填充,您需要绘制垂直线,而不是单个像素。为此,我使用ImageDraw.Draw.line()而不是im.putpixel()。图像背景也在WHITE调用中初始化为Image.new()

另请注意,所生成的图像将从大多数教科书中显示的图像上下颠倒,因为原点是左上角,y轴从那里到左下角。大多数插图的起源都在左下角。如果你愿意,你也可以解决这个问题。

from PIL import Image, ImageDraw

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

def parabola(x):
    return (-1) * (x ** 2)

def draw_function(function, size=200):
    min_y, max_y = 0, 0
    for x in range(size):
        val = function(x)
        if val < min_y:
            min_y = val
        if val > max_y:
            max_y = val
    delta = max_y - min_y

    im = Image.new("RGB", (size, size), WHITE)
    draw = ImageDraw.Draw(im)
    for x in range(size):
        y = int(((function(x)-min_y) / delta) * (size-1))
        draw.line([(x, 0), (x, y)], BLACK)
    im.show()

draw_function(parabola)

结果:

output showing parabola

© www.soinside.com 2019 - 2024. All rights reserved.