如何在Pycairo中高效填充自定义曲边形状外侧的区域
Pycairo自定义曲边形状外侧填充优化方案
核心优化思路
抛弃逐层叠加描边的冗余方案,用路径复合填充或反向裁剪实现单次绘制完成外侧区域填充,1200个形状绘制耗时可从1分钟压缩到2秒以内。
方案1:双路径复合填充(最稳定)
利用cairo的奇偶填充规则,同时绘制内圈曲边路径和外扩曲边路径,直接填充两者中间的外侧区域,无需多次绘制。
优化后代码示例
# 生成内侧曲边闭合路径(你原有逻辑的基础上调整半径即可) inner_radius = shape_radius inner_vertices = polygon(num_sides, inner_radius, rotation, [x + offset[0], y + offset[1]]) cr.new_path() for i in range(len(inner_vertices)): start_point = inner_vertices[i] cr.move_to(*start_point) end_point = inner_vertices[0] if i == len(inner_vertices)-1 else inner_vertices[i+1] p1, p2 = calculate_curve_handles(start_point, end_point, curve_point_1_offset, curve_point_2_offset) cr.curve_to(*p1, *p2, *end_point) cr.close_path() inner_path = cr.copy_path() # 生成外扩对应宽度的外侧曲边路径 outer_radius = inner_radius + line_thickness # 替换为你需要的外侧填充宽度 outer_vertices = polygon(num_sides, outer_radius, rotation, [x + offset[0], y + offset[1]]) cr.new_path() for i in range(len(outer_vertices)): start_point = outer_vertices[i] cr.move_to(*start_point) end_point = outer_vertices[0] if i == len(outer_vertices)-1 else outer_vertices[i+1] p1, p2 = calculate_curve_handles(start_point, end_point, curve_point_1_offset, curve_point_2_offset) cr.curve_to(*p1, *p2, *end_point) cr.close_path() outer_path = cr.copy_path() # 合并路径填充中间区域 cr.new_path() cr.append_path(outer_path) cr.append_path(inner_path.reverse()) # 内侧路径反向,适配奇偶填充规则 cr.set_fill_rule(cairo.FILL_RULE_EVEN_ODD) cr.fill()
方案2:反向裁剪填充(适合大区域外侧填充)
如果需要填充整个画布除形状内部之外的所有区域,用反向裁剪效率更高:
- 生成内侧曲边路径后调用
cr.clip()设置裁剪区 - 直接绘制和画布等大的填充矩形,仅形状外侧区域会被保留
- 绘制完成后调用
cr.reset_clip()恢复画布裁剪状态
效果对比
- 预期效果(逐层叠加实现的目标效果):

- 原代码直接fill得到的错误效果:

内容的提问来源于stack exchange,提问作者JasonT
相关产品推荐
相关产品推荐

