使用pyCairo

时间:2015-09-28 10:48:32

标签: python python-3.x svg polygons pycairo

我没有尝试使用pyCairo填充多边形,但我希望某些区域可以填充空白。例如,我想生产这样的东西:

enter image description here

灰色背景是SVG查看器的背景,因此代表图像的透明部分。

我尝试使用此代码:

import cairo

cairo.FILL_RULE_EVEN_ODD
svg_file_pointer = open('CairoPoly.svg', 'wb')
shape_container = cairo.SVGSurface(svg_file_pointer, 500, 500)
shape_description = cairo.Context(shape_container)
shape_description.rectangle(0, 0, 500, 500)
shape_description.clip_preserve()
shape_description.stroke()

shape_description.set_line_width(1)
shape_description.set_source_rgb(20/51, 0, 0)
for r in ((100, 100, 400, 400), (200, 200, 350, 300), (150, 110, 190, 390)):
    shape_description.move_to(r[0], r[1])
    shape_description.line_to(r[0], r[3])
    shape_description.line_to(r[2], r[3])
    shape_description.line_to(r[2], r[1])
    shape_description.line_to(r[0], r[1])
shape_description.close_path()
shape_description.fill()
shape_container.finish()
svg_file_pointer.close()
del shape_container

但它不起作用。可以用pyCairo完成,如果可以,怎么做?

2 个答案:

答案 0 :(得分:2)

我不熟悉pyCairo,但从SVG的角度来看,你所做的基本想法是正确的。你很近,但不是很正确。

您要做的是为每个矩形创建一个包含子路径的路径。



<svg width="500" height="500">
    <path d="M 100,100 L 100,400 L 400,400 L 400,100 L 100,100
             M 200,200 L 200,300 L 350,300 L 350,200 L 200,200
             M 150,110 L 150,390 L 190,390 L 190,110 L 150,110 Z"
          fill-rule="evenodd" />
</svg>
&#13;
&#13;
&#13;

看起来这或多或少是你正在做的事情,但你还需要将填充规则改为&#34; evenodd&#34;。默认值为&#34;非零&#34;会导致你的&#34;漏洞&#34;被填补而不是被留下来。

set_fill_rule(cairo.FILL_RULE_EVEN_ODD)

答案 1 :(得分:-1)

要获得带孔的多边形,需要定义轮廓。轮廓必须是一个笔划。部分重叠的边缘会引起问题。我的建议:太难做对了。

我看到两个解决方案:

  1. 将形状切割成可以填充的矩形,然后省略“透明”部分。
  2. 将外部矩形渲染为新的(屏幕外)图像。用透明颜色画出孔。然后用剩下的图像覆盖这个图像。
  3. 注意:有二维库可以为您交叉矩形。如果你有一个(在开罗甚至可能有一个),那么你可以让库通过对外部矩形应用布尔运算来计算必要的矩形列表(从中添加和删除矩形以获得矩形列表)。