我正在尝试使用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
答案 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.line
和width
选项绘制圆弧。
答案 3 :(得分:0)
我发现可以拉动的一个技巧是在黑色圆圈内制作一个白色圆圈。您可以根据需要使用pieslice方法将其分解。渲染是顺序的,所以你必须得到正确的顺序。由于Imagedraw使用了边界框而不是中心坐标和半径坐标,因此难以获得正确的定位。你必须确保所有事物的中心完全相互结合。
此解决方案仅在有限的情况下有效,请参阅评论。