【问题标题】:Filling a polygon with with multiple holes with pyCairo用 pyCairo 用多个孔填充多边形
【发布时间】:2015-09-28 10:48:32
【问题描述】:

我不想用pyCairo 填充多边形,但我希望某些区域不填充。例如,我想制作这样的东西:

灰色背景是 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 完成吗?如果可以,怎么做?

【问题讨论】:

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


    【解决方案1】:

    我不熟悉 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>

    看起来这或多或少是您正在做的事情,但您还需要将填充规则更改为“evenodd”。 “非零”的默认值将导致您的“洞”被填充,而不是被留作洞。

    set_fill_rule(cairo.FILL_RULE_EVEN_ODD)
    

    【讨论】:

    • 非常感谢。原来问题是我不知道如何处理cairo.FILL_RULE_EVEN_ODD。在我的示例中,我只是将它替换为 shape_description.set_fill_rule(cairo.FILL_RULE_EVEN_ODD),现在它就像一个魅力。
    【解决方案2】:

    要获得带孔的多边形,您需要定义轮廓。轮廓必须是单笔画。部分重叠的边缘会导致问题。我的建议:太难了。

    我看到了两种解决方案:

    1. 将形状剪成可以填充的矩形,简单地省略“透明”部分。
    2. 将外部矩形渲染为新的(屏幕外)图像。用透明颜色绘制孔。然后将这张图片与其他图片叠加。

    注意:有 2D 库可以为您与矩形相交。如果你有一个(开罗甚至可能有一个),那么你可以让库通过对外部矩形应用布尔运算来计算必要的矩形列表(添加和删除矩形以获取矩形列表)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-19
      • 2020-10-16
      • 2021-12-09
      • 2019-02-15
      • 1970-01-01
      • 2011-06-10
      相关资源
      最近更新 更多