在Python PIL中以线粗绘制椭圆 [英] Draw Ellipse in Python PIL with line thickness

查看:376
本文介绍了在Python PIL中以线粗绘制椭圆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Python在图像上画一个圆.我尝试使用PIL进行此操作,但我想指定一个linewidth.目前,PIL画了一个圆,但边界太细了.

I am trying to draw a circle on an image, using Python. I tried this using PIL but I would like to specify a linewidth. Currently, PIL draws a circle but the border is too thin.

这就是我所做的.

对于测试图像:我在MS Paint中创建了1632 X 1200图像,并将其填充为绿色.我称它为 test_1.jpg .这是输入文件:

For a test image: I created a 1632 X 1200 image in MS Paint and filled it green. I called it test_1.jpg. Here is the input file:

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()

基本上,我尝试绘制多个以相同点为中心但半径不同的圆.我的想法是,这将产生更粗线的效果.

Basically, I tried to draw multiple circles that would be centered at the same spot but with a different radius. My thinking was that this would create the effect of a thicker line.

但是,这将产生以下附件中所示的输出:

However, this is producing the output shown in the attached file below:

问题:如您所见,左下角和右上角太细了.此外,各个圆圈之间也存在间隙(请参见左上和右下).

Problem: As you can see, the bottom-left and top-right are too thin. Also, there are gaps between the various circles (see top left and bottom right).

该圆具有变化的厚度.我正在看一个厚度均匀的圆.

The circle has a varying thickness. I am looking a circle with a uniform thickness.

问题: 有没有办法在Python中使用PIL,NumPy等在 test_1.jpg 等图像上绘制圆,并指定线宽?

Question: Is there a way to do draw a circle in Python, on an image like test_1.jpg, using PIL, NumPy, etc. and to specify line thickness?

推荐答案

我遇到了同样的问题,因此决定编写一个类似于您的帮助函数.此功能在蒙版层上绘制两个黑白的同心椭圆,然后通过蒙版将所需的轮廓颜色压印到原始图像上.为了获得更平滑的结果(抗锯齿),将以更高的分辨率绘制椭圆和蒙版.

I had the same problem, and decided to write a helper function, similar to yours. This function draws two concentric ellipses in black and white on a mask layer, and the intended outline colour is stamped onto the original image through the mask. To get smoother results (antialias), the ellipses and mask is drawn in higher resolution.

白色椭圆为20像素宽,黑色椭圆为0.5像素宽.

The white ellipse is 20 pixels wide, and the black ellipse is 0.5 pixels wide.

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()

我只在python 3.4中测试过此代码,但我认为它无需更改即可在2.7上运行.

I've only tested this code in python 3.4, but I think it should work with 2.7 without major modification.

这篇关于在Python PIL中以线粗绘制椭圆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆