python - 用线条粗细在Python PIL中绘制椭圆

标签 python python-2.7 python-imaging-library

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

这是我所做的。

对于测试图像:我在 MS Paint 中创建了一个 1632 X 1200 图像并将其填充为绿色。我将其命名为 test_1.jpg。这是输入文件: 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

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

圆的厚度是变化的。我正在寻找一个厚度均匀的圆。

问题: 有没有一种方法可以使用 PIL、NumPy 等在 test_1.jpg 这样的图像上用 Python 画一个圆,并指定线宽

最佳答案

我遇到了同样的问题,因此决定编写一个类似于您的辅助函数。该函数在 mask 层上绘制黑白两个同心椭圆,将想要的轮廓颜色通过 mask 印在原图上。为了获得更平滑的结果(抗锯齿),椭圆和蒙版以更高分辨率绘制。

带和不带抗锯齿的输出

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

我只在 python 3.4 中测试过这段代码,但我认为它应该可以在 2.7 上运行而无需进行重大修改。

关于python - 用线条粗细在Python PIL中绘制椭圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32504246/

相关文章:

python - 如何删除两个文件中相同的单词?

python - BeautifulSoup4 无法在我的托管服务器上运行

python - 使用 PIL 加载和评估像素

text - 获取TKINTER中屏幕上显示的文本的位置/坐标和大小

python - OpenCV 图像转换为 PIL 后无法解码二维码

python - 如何找到netCDF数组除零之外的最小值

python - 查找可能包含 NAN 的一维数组的最大值

python - 需要一种巧妙的方法来为 pygame/pyOpenGL 项目创建一个大列表

python - Pandas cut 函数提供的类别少于预期

python - Pandas - GroupBy 然后在原始表上合并