2011-03-23 37 views
0

这是我现在使用的代码:开罗(w/Python):是否可以使用透明线填充多边形?

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, *image.size) 
context = cairo.Context(surface) 
context.set_source_rgba(1, 1, 1, 1) 
context.new_path() 
for i in xrange(len(points)): 
    context.line_to(*points[i]) 

context.close_path() 
context.fill() 

的问题是,它填补了相同的颜色我绘制多边形。我试图在这个画一个新的多边形,只做context.stroke(),而不是fill(),但只有当我使用不同的颜色,因为否则白色是在下面。我试着用(0,0,0,0),所以它会是透明的,但是然后白色在它下面。

我可以得出一个颜色的线(比如(0.5,0.5,0.5,1)),它与write_to_png保存为图像,与PIL加载,转换为numpy.array和更换正确的颜色与背景颜色(0, 0, 0, 0)每个像素,但是这不是高效。

我也尝试将线宽设置为0,这也不起作用。

此外,我很好,其他方法,让我这样做,而不是开罗。我尝试过ImageDraw的polygon,但它没有绘制出确切的形状(我不确定如何解释,但它在多边形之外绘制一些额外的像素,它不应该),所以ImageDraw不会帮助我。

+0

我不能正是你想要的了解。一个人不会用“线”“填充”一个形状 - 你想做什么?如果yu只想要多边形的轮廓,请尝试使用“.stroke()”而不是“.fill()”。如果您希望绘图颜色透明,请为Alpha使用中间值(颜色中的第四个元素 - 您将其始终设置为1) – jsbueno 2011-03-23 02:27:09

+0

当我使用填充时,它会在多边形上绘制轮廓。我不想要那个轮廓/线条。 – pppphhhhuuuu 2011-03-23 02:31:04

回答

0

我明白了。所以没有办法做到这一点 - 所有关于开罗风格的2D绘图API都假设“填充”包含边界。它在Cairo提供的大多数后端上都是这样工作的,比如Postscript和SVG,所以很难想象它可能会有什么不同。

“干净”的方法是迭代你的多边形,这样你就可以生成只限定你不填充区域的点 - 也就是说,你必须自己计算线区域。

另一方面,你的破解似乎很聪明,因为它处理光栅是不可能在开罗完全完成的。但是,除了保存到磁盘并重新加载之外,还可以采用其他方法 - 例如,您可以在Pygame中将开罗表面数据用作SDL表面来伪造“复制和粘贴”操作。

http://doswa.com/blog/2010/03/29/using-cairo-in-pygame/ http://www.pygame.org/wiki/CairoPygame

(其实,.我试着想用Pyagame工作流程和不能 - 选项 操纵阿尔法像素和复制/粘贴在它上面是相当有限的)。

我的最终建议是:不要使用pycairo - 检查使用GIMP Python API是否适合您。 GIMP是一个功能齐全的2D绘图程序,具有可从Python使用的完整API。例如,您可以使用GIMP“矢量”对象绘制yur多边形,并且尽管“填充” 也将包含多边形线,但在填充之前您可以调用jsut,例如“gimp_selection_shrink”。或者,您可以使用图层来获得所需的确切效果。

从GIMP内部,您可以在帮助 - >程序数据库菜单中检查整个API。

脚本准备就绪后,可以通过coomand行运行GIMP来运行程序,而不需要图形显示。

以下是你需要使用pygimp工作流程:

  • 创建GIMP向量与poligon分对象: pdb.gimp_image_add_vectors,pdb.gimp_vectors_stroke_new_from_points
  • 创建一个新层(与图像层以上你想保留沿着这条线) pdb.gimp_layer_new(还有一些其他函数必须调用以将图层绑定到图像上)
  • 将您的多边形转换为选区 - pdb.gimp_vectors_to_selection
  • 填入新层,将具有所需颜色pdb.gimp_edit_bucket_fill
  • 从层转换的选择,以“厚”的选择与 pdb.gimp_selection_border
  • 剪切像素 - pdb.gimp_Edit_cut
  • 合并新层到以前的形象 - pdb.gimp_image_merge_down
1
fill_preserve() 
context.set_source_rgba(0, .6, 1, .7) #line color 
context.set_line_width(2.35) 
context.stroke()