用Python-PIL绘制线厚椭圆

2024-05-18 18:57:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python在图像上画一个圆。我使用PIL尝试了这个,但是我想指定一个linewidth。目前,皮尔画了一个圆圈,但边界太薄。

这就是我所做的。

对于测试图像:我用MS Paint创建了一个1632x 1200的图像,并将其填充为绿色。我称之为测试。以下是输入文件: Input

from PIL import Image, ImageDraw

im = Image.open('test_1.jpg')

width, height = im.size
eX, eY = 816,816 #Size of Bounding Box for ellipse

bbox =  (width/2 - eX/2, height/2 - eY/2, width/2 + eX/2, height/2 + eY/2)

draw = ImageDraw.Draw(im)
bbox_L = []
for j in range(0,5):
    bbox_L.append([element+j for element in bbox])
    draw.ellipse(tuple(bbox_L[j]), outline ='white')

im.show()

基本上,我试着画多个圆心在同一点,但半径不同的圆。我的想法是这样会产生一个更粗的线条的效果。

但是,这将生成如下所附文件中所示的输出: Output

问题:如您所见,左下角和右上角太薄。此外,各个圆之间也有间隙(请参见左上角和右下角)。

这个圆有不同的厚度。我在看一个厚度均匀的圆。

问题: 有没有办法用Python在像test_1.jpg这样的图像上画一个圆,使用PIL、NumPy等来指定线的厚度?


Tags: 文件test图像imageforpilwidthex
3条回答

我也遇到了同样的问题,决定编写一个helper函数,与您的类似。此函数用于在遮罩层上绘制两个黑白同心椭圆,并通过遮罩将所需的轮廓颜色压印到原始图像上。为了获得更平滑的结果(抗锯齿),椭圆和遮罩以更高的分辨率绘制。

带和不带反别名的输出

ellipses with PIL

白色椭圆宽20像素,黑色椭圆宽0.5像素。

代码

from PIL import Image, ImageDraw

def draw_ellipse(image, bounds, width=1, outline='white', antialias=4):
    """Improved ellipse drawing function, based on PIL.ImageDraw."""

    # Use a single channel image (mode='L') as mask.
    # The size of the mask can be increased relative to the imput image
    # to get smoother looking results. 
    mask = Image.new(
        size=[int(dim * antialias) for dim in image.size],
        mode='L', color='black')
    draw = ImageDraw.Draw(mask)

    # draw outer shape in white (color) and inner shape in black (transparent)
    for offset, fill in (width/-2.0, 'white'), (width/2.0, 'black'):
        left, top = [(value + offset) * antialias for value in bounds[:2]]
        right, bottom = [(value - offset) * antialias for value in bounds[2:]]
        draw.ellipse([left, top, right, bottom], fill=fill)

    # downsample the mask using PIL.Image.LANCZOS 
    # (a high-quality downsampling filter).
    mask = mask.resize(image.size, Image.LANCZOS)
    # paste outline color to input image through the mask
    image.paste(outline, mask=mask)

# green background image
image = Image.new(mode='RGB', size=(700, 300), color='green')

ellipse_box = [50, 50, 300, 250]

# draw a thick white ellipse and a thin black ellipse
draw_ellipse(image, ellipse_box, width=20)

# draw a thin black line, using higher antialias to preserve finer detail
draw_ellipse(image, ellipse_box, outline='black', width=.5, antialias=8)

# Lets try without antialiasing
ellipse_box[0] += 350 
ellipse_box[2] += 350 

draw_ellipse(image, ellipse_box, width=20, antialias=1)
draw_ellipse(image, ellipse_box, outline='black', width=1, antialias=1)

image.show()

我只在Python3.4中测试过这段代码,但我认为它应该在没有重大修改的情况下与2.7一起工作。

简单(但不好)的解决方案是画两个圆(较小的一个带有背景色):

outline = 10 # line thickness
draw.ellipse((x1-outline, y1-outline, x2+outline, y2+outline), fill=outline_color)
draw.ellipse((x1, y1, x2, y2), fill=background_color)

我不认为有办法指定椭圆的厚度,但您可能可以在椭圆通过的每个像素处画线,参数width=。。。

注:我是外国人,如果我的英语错了,很抱歉。

相关问题 更多 >

    热门问题