这是使用aggdraw与PIL图像
所以我尝试用贝塞尔曲线生成一些形状。但问题是删除图形的内部部分。如果我使用一个内部和外部路径,它只会填充这两个路径,如果我将它们分开,并使用一个透明的笔刷填充内部路径,它不会做任何事情
比如说,如果你想画一个油炸圈饼,你怎么去掉这个洞
似乎不可能用aggdraw擦除像素,所以。。。。也许我错过了什么
问题一:你能用透明画笔在像素变为透明的地方画画吗
问题二:如何擦除像素、多边形和路径?。当然,我可以使用遮罩,但我必须创建遮罩,所以回到同样的问题
最后,这里有一些图片是我的要点,下面的链接。一种是使用代码生成的路径数据,然后使用gimp进行绘制,即目标渲染。另一个是从我的代码中实际生成的图像
要点示例:[https://gist.github.com/ismaelharunid/49df974a59ad98be6934deb8d38154ce
from PIL import Image
import aggdraw
from math import sqrt, cos, sin, pi
lerp = lambda a, b=0.0, t=0.5: a + (b-a) * t
circle4k = 0.55191502449
radius_circle_bpd = lambda radius: \
( 0., radius
, circle4k*radius, radius
, radius, circle4k*radius
, radius, 0.
, radius, -circle4k*radius
, circle4k*radius, -radius
, 0., -radius
, -circle4k*radius, -radius
, -radius, -circle4k*radius
, -radius, 0.
, -radius, circle4k*radius
, -circle4k*radius, radius
, 0., radius )
rectangle_pd = lambda x0,y0, x1,y1: (x0,y0, x1,y0, x1,y1, x0,y1, x0,y0)
pd_translate = lambda pd, offset, nc=2: tuple( pd[ir+ic] + offset[ic] \
for ir in range(0, len(pd), nc) for ic in range(nc) )
pd_scale = lambda pd, delta, nc=2: tuple( pd[ir+ic] * delta[ic] \
for ir in range(0, len(pd), nc) for ic in range(nc) )
pd_transform = lambda pd, m, nc=2: \
tuple(sum(pd[ir+i]*m[ic+i*nc] for i in range(nc)) \
for ir in range(0, len(pd), nc) for ic in range(nc))
new_draw = lambda size: aggdraw.Draw(Image.new("RGBA", size))
def bpd_add_path(*bpds, path=None):
if path is None: path = aggdraw.Path()
for bpd in bpds:
path.moveto(*bpd[:2])
for i in range(2, len(bpd), 6):
path.curveto(*bpd[i:i+6])
return path
def saturn_im(size=(540, 540), angle=pi/10, circle_radius=None
, ring_inner_radius=None, ring_outer_radius=None
, n_rings=3, ring_ratio=0.85, ring_aspect=0.5
, circle_color='#bc75ff', rings_color='#bcff75'
, outline_color='#ccbd14', outline_weight=4.5):
offset = (.5 * size[0], .5 * size[1])
if circle_radius is None:
circle_radius = min(offset) / 3.
if ring_inner_radius is None:
ring_inner_radius = circle_radius / .80
if ring_outer_radius is None:
ring_outer_radius = offset[0]
ca, sa = cos(angle), sin(angle)
matrix = (ca, sa,-sa, ca)
pdmask = \
pd_translate( \
pd_transform( \
rectangle_pd(-offset[0],-offset[1], offset[0],offset[1]) \
, matrix )
, offset )
bpdcircle = \
pd_translate( \
pd_transform( \
radius_circle_bpd(circle_radius) \
, matrix )
, offset )
r0, r1 = ring_ratio**5, ring_ratio**0
rspan, sspan = r1 - r0, ring_outer_radius - ring_inner_radius
rlerp = lambda i: ring_inner_radius+sspan*(ring_ratio**i-r0) / rspan
bpdrings = tuple( \
pd_translate( \
pd_transform( \
pd_scale( \
radius_circle_bpd(rlerp(i_rings)) \
, (1.0, ring_aspect) )
, matrix )
, offset ) for i_rings in range(n_rings * 2))
for i in range(6):
print(i, min(bpdrings[i]),max(bpdrings[i]))
print("Paths created")
penstroke = aggdraw.Pen(outline_color, outline_weight)
brushcircle = aggdraw.Brush(circle_color)
brushrings = aggdraw.Brush(rings_color)
brusheraser = aggdraw.Brush((0,0,0,0))
print("Resources created")
imcircle = new_draw(size)
imcircle.path(bpd_add_path(bpdcircle), penstroke, brushcircle)
imcircle = imcircle.flush()
print("Circle created")
imrings = new_draw(size)
#imrings.path(bpd_add_path(*bpdrings), penstroke, brushrings)
#imrings.path(bpd_add_path(bpdrings[0]), penstroke, brushrings)
#imrings.path(bpd_add_path(bpdrings[1]), penstroke, brusheraser)
imrings.path(bpd_add_path(bpdrings[2]), penstroke, brushrings)
imrings.path(bpd_add_path(bpdrings[3]), penstroke, brusheraser)
#imrings.path(bpd_add_path(bpdrings[4]), penstroke, brushrings)
#imrings.path(bpd_add_path(bpdrings[5]), penstroke, brusheraser)
imrings = imrings.flush()
print("Rings created")
im = Image.new("RGBA", size, '#000000')
im.paste(imrings, mask=imrings)
im.paste(imcircle, mask=imcircle)
print("Doughnut created")
return im
好的,所以我的问题仍然存在,但我找到了一个解决办法,这可能是大多数人的做法。使用面具,我可以在L模式(灰度)下画画然后是在东方画出来,或者在你想做的每一件事上做面具。然后你必须应用面具。有点乏味,但它完成了工作。修改后的代码有效
from PIL import Image
import aggdraw
from math import sqrt, cos, sin, pi
lerp = lambda a, b=0.0, t=0.5: a + (b-a) * t
circle4k = 0.55191502449
radius_circle_bpd = lambda rx, ry=None: _radius_circle_bpd(rx, rx if ry is None else ry)
_radius_circle_bpd = lambda rx, ry: \
( 0., ry
, circle4k*rx, ry
, rx, circle4k*ry
, rx, 0.
, rx, -circle4k*ry
, circle4k*rx, -ry
, 0., -ry
, -circle4k*rx, -ry
, -rx, -circle4k*ry
, -rx, 0.
, -rx, circle4k*ry
, -circle4k*rx, ry
, 0., ry )
rectangle_pd = lambda x0,y0, x1,y1: (x0,y0, x1,y0, x1,y1, x0,y1, x0,y0)
pd_translate = lambda pd, offset, nc=2: tuple( pd[ir+ic] + offset[ic] \
for ir in range(0, len(pd), nc) for ic in range(nc) )
pd_scale = lambda pd, delta, nc=2: tuple( pd[ir+ic] * delta[ic] \
for ir in range(0, len(pd), nc) for ic in range(nc) )
pd_transform = lambda pd, m, nc=2: \
tuple(sum(pd[ir+i]*m[ic+i*nc] for i in range(nc)) \
for ir in range(0, len(pd), nc) for ic in range(nc))
new_draw = lambda size: aggdraw.Draw(Image.new("RGBA", size))
new_mask = lambda size, color="black": aggdraw.Draw(Image.new("L", size, color))
def bpd_add_path(*bpds, path=None):
if path is None: path = aggdraw.Path()
for bpd in bpds:
path.moveto(*bpd[:2])
for i in range(2, len(bpd), 6):
path.curveto(*bpd[i:i+6])
return path
def pd_add_path(*bpds, path=None):
if path is None: path = aggdraw.Path()
for bpd in bpds:
path.moveto(*bpd[:2])
for i in range(2, len(bpd), 2):
path.lineto(*bpd[i:i+2])
return path
def saturn_im(size=(540, 540), angle=pi/10, circle_radius=None
, ring_inner_radius=None, ring_outer_radius=None
, n_rings=3, ring_ratio=0.85, ring_aspect=0.5
, circle_color='#bc75ff', rings_color='#bcff75'
, outline_color='#ccbd14', outline_weight=4.5):
offset = (.5 * size[0], .5 * size[1])
if circle_radius is None:
circle_radius = min(offset) / 3.
if ring_inner_radius is None:
ring_inner_radius = circle_radius / .80
if ring_outer_radius is None:
ring_outer_radius = offset[0]
ca, sa = cos(angle), sin(angle)
matrix = (ca, sa,-sa, ca)
pdmask = \
pd_translate( \
pd_transform( \
rectangle_pd(-offset[0],-offset[1], offset[0],0) \
, matrix )
, offset )
bpdcircle = \
pd_translate( \
pd_transform( \
radius_circle_bpd(circle_radius) \
, matrix )
, offset )
r0, r1 = ring_ratio**(n_rings*2-1), ring_ratio**0
rspan, sspan = r1 - r0, ring_outer_radius - ring_inner_radius
rlerp = lambda i: ring_inner_radius+sspan*(ring_ratio**i-r0) / rspan
bpdrings = tuple( \
pd_translate( \
pd_transform( \
pd_scale( \
radius_circle_bpd(rlerp(i_rings)) \
, (1.0, ring_aspect) )
, matrix )
, offset ) for i_rings in range(n_rings * 2))
for i in range(6):
print(i, min(bpdrings[i]),max(bpdrings[i]))
print("Paths created")
penstroke = aggdraw.Pen(outline_color, outline_weight)
penwhite = aggdraw.Pen("white", outline_weight)
penblack = aggdraw.Pen("black", outline_weight)
brushcircle = aggdraw.Brush(circle_color)
brushrings = aggdraw.Brush(rings_color)
brushwhite = aggdraw.Brush("white")
brushblack = aggdraw.Brush("black")
print("Resources created")
imcircle = new_draw(size)
imcircle.path(bpd_add_path(bpdcircle), penstroke, brushcircle)
imcircle = imcircle.flush()
print("Circle created")
imcirclemask = new_mask(size, "white")
imcirclemask.path(bpd_add_path(bpdcircle), penblack, brushblack)
imcirclemask.path(pd_add_path(pdmask), brushwhite)
imcirclemask = imcirclemask.flush()
#imcirclemask.show()
print("Circle mask created")
imrings = new_draw(size)
imrings.path(bpd_add_path(*bpdrings), penstroke, brushrings)
imrings = imrings.flush()
#imrings.show()
print("Rings created")
tmpmask = new_mask(size, "black")
for i in range(0, 2*n_rings, 2):
tmpmask.path(bpd_add_path(bpdrings[i+0]), penwhite, brushwhite)
tmpmask.path(bpd_add_path(bpdrings[i+1]), penwhite, brushblack)
tmpmask = tmpmask.flush()
#tmpmask.show()
imringsmask = Image.new("L", size, "black")
imringsmask.paste(tmpmask, mask=imcirclemask)
#imringsmask.show()
print("Rings mask created")
im = Image.new("RGBA", size, '#000000')
im.paste(imcircle, mask=imcircle)
im.paste(imrings, mask=imringsmask)
print("Doughnut created")
return im
还有塔达
[https://user-images.githubusercontent.com/26759688/84541494-16bdf180-ad2a-11ea-805e-29388f992070.png
目前没有回答
相关问题 更多 >
编程相关推荐