开罗(带Python):是否可以用透明线填充多边形?

时间:2011-03-23 02:12:13

标签: python image drawing cairo

这是我现在正在使用的代码:

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不会帮助我。

2 个答案:

答案 0 :(得分:1)

fill_preserve()
context.set_source_rgba(0, .6, 1, .7) #line color
context.set_line_width(2.35)
context.stroke()

答案 1 :(得分:0)

我现在明白了。所以,没有办法做到这一点 - 开罗风格的所有2D绘图API都假设“填充”包括边框。它在大多数后端上以这种方式工作,就像Postscript和SVG一样,所以很难想象它会有什么不同。

执行此操作的“干净”方法是迭代多边形,以便生成仅限定您要填充的区域的点 - 即,您必须自己计算线条区域。

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

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

(实际上,我试图用Pyagame来思考一个工作流程,而不是 - 选项 对于操纵alpha像素和复制/粘贴它是相当有限的。)

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

从GIMP内部,您可以在Help-> Procedure数据库菜单中查看整个API。

一旦你的脚本准备就绪,就可以用一个cumand行来运行GIMP来运行你的程序,而不需要图形显示。

以下是使用pygimp所需的工作流程:

  • 使用您的poligon积分创建GIMP向量对象: 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