使用PIL的Imagedraw创建具有给定厚度的圆弧

时间:2011-08-15 21:13:07

标签: python image drawing python-imaging-library

我正在尝试使用PIL和Imagedraw创建分段弧。弧功能允许我轻松绘制弧线,但它只是一条线。我需要能够放置一个给定半径和厚度的弧(ID到OD),但AI找不到任何类型的厚度或宽度设置。有没有办法做到这一点?如果没有,还有其他方法可以使用PIL吗?

段:

import Image
import ImageDraw

conv = 0.1
ID = 15
OD = 20
image = Image.new('1',(int(ceil(OD/conv))+2,int(ceil(OD/conv))+1), 1)
draw = ImageDraw.Draw(image)
diam = OD-ID
box=(1, 1, int(ceil(diam/conv)), int(ceil(diam/conv))) #create bounding box
draw.arc(box, 0, 90, 0) #draw circle in black

4 个答案:

答案 0 :(得分:1)

PIL无法绘制宽弧,但Aggdraw可以,并且与PIL(同一作者)合作良好。

答案 1 :(得分:1)

我根据Mark的建议创建了以下弧替换功能:

https://gist.github.com/skion/9259926

可能不像素完美(也不快),但似乎接近我所需要的。如果您有更好的版本,请在Gist中发表评论。

def arc(draw, bbox, start, end, fill, width=1, segments=100):
    """
    Hack that looks similar to PIL's draw.arc(), but can specify a line width.
    """
    # radians
    start *= math.pi / 180
    end *= math.pi / 180

    # angle step
    da = (end - start) / segments

    # shift end points with half a segment angle
    start -= da / 2
    end -= da / 2

    # ellips radii
    rx = (bbox[2] - bbox[0]) / 2
    ry = (bbox[3] - bbox[1]) / 2

    # box centre
    cx = bbox[0] + rx
    cy = bbox[1] + ry

    # segment length
    l = (rx+ry) * da / 2.0

    for i in range(segments):

        # angle centre
        a = start + (i+0.5) * da

        # x,y centre
        x = cx + math.cos(a) * rx
        y = cy + math.sin(a) * ry

        # derivatives
        dx = -math.sin(a) * rx / (rx+ry)
        dy = math.cos(a) * ry / (rx+ry)

        draw.line([(x-dx*l,y-dy*l), (x+dx*l, y+dy*l)], fill=fill, width=width)

答案 2 :(得分:0)

使用直线段模拟圆弧,并将这些线段的坐标放入列表中。使用draw.linewidth选项绘制圆弧。

答案 3 :(得分:0)

我发现可以拉动的一个技巧是在黑色圆圈内制作一个白色圆圈。您可以根据需要使用pieslice方法将其分解。渲染是顺序的,所以你必须得到正确的顺序。由于Imagedraw使用了边界框而不是中心坐标和半径坐标,因此难以获得正确的定位。你必须确保所有事物的中心完全相互结合。

此解决方案仅在有限的情况下有效,请参阅评论。