跳转到主要内容

SVG路径对象和解析器

项目描述

svg.path

svg.path 是一个实现SVG中不同路径命令的对象集合,以及SVG路径定义的解析器。

用法

有四个路径段对象,分别是 Line(直线)、Arc(弧线)、CubicBezier(三次贝塞尔曲线)和 QuadraticBezier(二次贝塞尔曲线)。还有一个 Path 对象,它作为一个路径段对象的集合。

这些类的所有坐标值都作为 complex 值给出,其中 .real 部分代表X坐标,而 .imag 部分代表Y坐标。

>>> from svg.path import Path, Move, Line, Arc, CubicBezier, QuadraticBezier, Close

这些对象都有一个 .point() 函数,它将返回路径上一点的坐标,其中点以浮点值给出,其中 0.0 是路径的起点,而 1.0 是路径的终点。

您可以使用 .length() 函数计算路径或其段落的长度。对于CubicBezier和Arc段,这是通过几何近似完成的,因此可能非常慢。您可以通过传递一个 error 选项到该方法来加快速度。如果不传递错误,则默认为 1e-12

>>> CubicBezier(300+100j, 100+100j, 200+200j, 200+300j).length(error=1e-5)
297.2208145656899

三次贝塞尔和圆弧也具有一个 min_depth 选项,用于指定最小递归深度。默认设置为5,这意味着计算至少使用32个段。将其设置为0对于三次贝塞尔来说是一个坏主意,因为它们可能会被近似为一条直线。

Line.length()QuadraticBezier.length() 也接受这些参数,但它们会被忽略。

三次贝塞尔和二次贝塞尔还具有 is_smooth_from(previous) 方法,用于检查段与给定段相比是否是“平滑”的。

还有一个 parse_path() 函数,它将接受一个SVG路径定义并返回一个 Path 对象

>>> from svg.path import parse_path
>>> parse_path('M 100 100 L 300 100')
Path(Move(to=(100+100j)), Line(start=(100+100j), end=(300+100j)))

这些都是SVG路径段类。有关每个参数的更多信息,请参阅 SVG规范

  • Line(start, end)

  • Arc(start, radius, rotation, arc, sweep, end)

  • QuadraticBezier(start, control, end)

  • CubicBezier(start, control1, control2, end)

除此之外,还有一个 Path 类,它通过一系列路径段进行实例化

  • Path(*segments)

Path 类是一个可变序列,所以它表现得像列表。你可以向其中添加内容,替换路径段等

>>> path = Path(Move(200+100j), Line(200+100j,100+200j), Line(100+200j,300+100j))
>>> path.append(QuadraticBezier(300+100j, 200+200j, 200+300j))
>>> path[0] = Move(200+100j)
>>> del path[1]

路径对象还有一个 d() 方法,它将返回路径段的SVG表示

>>> path.d()
'M 200,100 L 300,100 Q 200,200 200,300'

请注意,在以这种方式操作线条时,目前没有内部一致性检查。此路径现在有一个不同的内部表示,与它的 d() 路径不同。注意,Line() 段的起始位置与 Move() 段所说的位置不同。这 可能在 未来版本中改变,并且路径操作方法 可能 会被修改以确保一致性。

>>> path
Path(Move(to=(200+100j)), Line(start=(100+200j), end=(300+100j)),
QuadraticBezier(start=(300+100j), control=(200+200j), end=(200+300j),
smooth=False))

示例

此SVG路径示例绘制了一个三角形

>>> path1 = parse_path('M 100 100 L 300 100 L 200 300 z')

你可以以许多不同的方式格式化SVG路径,所有有效的路径都应被接受

>>> path2 = parse_path('M100,100L300,100L200,300z')

并且这些路径应该是相等的

>>> path1 == path2
True

你也可以从对象构建路径

>>> path3 = Path(Line(100+100j,300+100j), Line(300+100j, 200+300j), Line(200+300j, 100+100j))

并且它应该再次等于第一个路径

>>> path1 == path2
True

路径是可变序列,你可以切片和追加

>>> path1.append(QuadraticBezier(300+100j, 200+200j, 200+300j))
>>> len(path1[2:]) == 3
True

请注意,没有防止你创建无效路径的保护。例如,你可以有一个不结束在路径起始位置的闭合命令

>>> wrong = Path(Line(100+100j,200+100j), Close(200+300j, 0))

未来特性

  • 反转路径。然后它们应该“反向”绘制,这意味着每个路径段也需要被反转。

  • 数学变换可能是有意义的。

  • 验证路径是否正确,或防止创建不正确的路径。

许可证

本模块受MIT许可证的约束。

贡献者

Lennart Regebro <regebro@gmail.com>,原始作者

Justin Gruenberg实现了二次贝塞尔的计算,并提供了关于 d() 函数的建议和反馈。

Michiel Schallig建议通过递归直线近似计算长度,这使你可以选择精度或速度。Steve Schwarz添加了一个错误参数来使这个选择成为参数。

ClayJarCom加快了路径的 point() 计算速度。

还要感谢以下错误修复者:Martin R、abcjjy、Daniel Stender、MTician、blokhin、Karthikeyan、jaraco、martinleopold 和 twjang。

还要感谢tatarize在调查问题和提出许多反馈和想法方面的帮助。

Samuel Carlsson [vidstige] 提供了 tangent() 函数。

Lucas Simon发现并修复了在解析时并非所有路径段都保留了相对设置的问题。

Taewoong Jang [twjang] 实现了 boundingbox 函数。

变更日志

6.3 (2023-04-29)

  • 修复了‘H’/‘h’命令的序列化。

  • 新的 boundingbox() 方法允许你获取路径的 boundingbox()[twjang]。

  • 测试现在位于源目录之外,这是现在的常见做法。

  • 弃用Python 3.6和3.7,添加了对3.10和3.11的支持。

6.2 (2022-06-17)

  • 允许带有小数点的数字,但不允许有小数部分,因为其他解析器也是这样。

  • 重新启用了 README.rst 的 doctest,该 doctest 在切换到 pytest 时丢失。

6.1 (2022-06-09)

  • 并非所有路径段都保留了相对设置。[Lucas-C]

6.0 (2022-04-14)

  • 从 6.0b1 版本没有功能上的变化,只是对测试进行了更改。

6.0b1 (2022-04-02)

  • 添加了新的抽象基类:PathSegment 和 NonLinear。现在,Linear 也从 PathSegment 继承,并且将来可能会成为抽象的。

  • 添加了平滑支持

    • CubicBezier 和 QuadraticBezier 现在有一个“平滑”标志,如果 SVG 路径有平滑段,则在解析时将其设置。

    • 如果路径元素设置了平滑标志,则现在将仅将其指定为平滑段。这意味着一个实际上是平滑的路径,但没有从平滑(S 和 T)段解析出来,将不会表示为平滑。路径段也必须是平滑的,因此如果您解析一个包含平滑段的路径,并将其修改得不再平滑,则无论标志如何,都不会表示为平滑。

    • CubicBezier 和 QuadraticBezier 现在有一个“set_smooth_from”标志,它将调整起始点和第一个控制点,以便曲线平滑。它还设置平滑标志。

  • 添加了对保留垂直/水平命令的支持。

  • 重构了 SVG 路径文本的生成,每个段现在都生成自己的段文本,具有一个 _d(self, previous) 方法。

5.1 (2022-03-23)

  • 添加了 SVG 标准测试。[tatarize]

  • 允许随机字符结束解析。

  • #61:修复了几乎线性的 QuadradicBeziers 的 length() 计算。[tatarize, regebro]

5.0.1 (2022-03-21)

  • 省略了两个新的测试文件。

5.0.0 (2022-03-21)

  • 删除了对 Python 2 的支持,以及 3.4 到 3.6。新的最小 Python 版本是 3.7。

  • 新解析器解决了弧标志和空格问题。请参阅问题 #53 和 #69。

  • 修复了 #60:处理长度为 0 的路径。[感谢 martinleopold 和 tatarize]

  • 在路径对象上添加了新方法:.tangent(point),它返回一个向量,该向量是曲线在该点的导数/切线。[vidstige]

  • 添加了新的图形测试。该测试需要 Pillow,所以我停止了 PyPy 的测试,因为它支持得太复杂了。但在 PyPy 上仍然可以工作。

4.1 (2021-02-16)

  • 使用 collections.abc 为 ABC 导入添加 Python 3.9 兼容性。

4.0.2 (2019-11-04)

  • [Alex Grönholm] 为 setup.cfg 提供了解决方案。

4.0.1 (2019-11-03)

else

raise

  • 纯 setup.cfg 配置没有工作。所有测试都通过,但在其他地方安装包时,没有任何东西被安装。所以我现在正在回滚这个更改。

4.0 (2019-11-02)

  • 将所有信息从 setup.py 移动到 setup.cfg。

  • 添加了一个与 Line() 命令没有任何区别的 Close() 命令,以简化对 closepath 命令和子路径的处理。

  • Path() 现在不再有 closed 属性。

  • 现在完全支持 SVG 1.1 “F.6.2 超出范围的参数”列表。

  • 使用圆数学计算圆弧长度,更准确,更快。

3.1 (2019-10-25)

  • Move 空命令没有被导入到 __init__.py [blokhin]

  • #41:从 svg 的 pkg_resource 样式命名空间包切换到 pkgutil 样式命名空间包。

  • 为路径添加了更快的 point() 实现。[ClayJarCom]

  • 删除了对 Python 2.6 和 Python 3.3 的支持。

  • 添加了对 Python 3.7 和 3.8 的支持。

3.0 (2018-08-14)

  • 删除了对 Python 3.1 和 3.2 的支持。它仍然可以工作,但它可能会停止。添加了对 Python 3.6 的支持。删除了对 Jython 的支持,因为它不受 Travis 支持,并且已经有一年多没有发布新版本了。

  • #33:解析时现在会保留移动命令。

  • 即使连接,子路径也不再合并。

  • #30:终点与起点相同的弧导致崩溃。SVG 规范说,它应该等效于跳过该部分,现在就是这样处理的。

2.2 (2016-10-15)

  • 关闭路径时,如果不需要,不要添加行。

2.1.1 (2016-02-28)

  • #18:在特定情况下,QuadraticBeziers可能会出现除以零的错误。[MTician]

  • 通过接受Path.point()的错误参数来控制错误与性能设置。[saschwarz]

  • #25:在特定情况下,弧可能会创建MathDomain错误。

  • #17:始终设置last_command。

2.0.1 (2015-10-17)

  • #20:closed()设置器的doctext不正确。

  • #19:修复后,测试没有使用相对路径。[danstender]

2.0 (2015-05-15)

  • 尚未有任何更改。

2.0b1 (2014-11-06)

  • 添加了一个Path.d()函数来生成路径的d属性。

  • 在QubicBezier和QuadradicBezier上添加了is_smooth_from()。

  • Path()现在有了一个.closed属性。

  • 修复了表示,使其可解析。

  • 现在,CubicBezier和Arc段落的计算是递归的,并且将在达到特定精度时结束。这对于弧来说速度更快,而对于CubicBezier来说速度更慢。然而,您现在可以指定精度,因此如果您想要更快但更宽松的计算,您可以实现这一点。

  • 如果前面的段不是QuadraticBezier,'t'段(平滑、相对QuadraticBeziers)将获得一个错误的控制点。

1.2 (2014-11-01)

  • 新的二次贝塞尔实现。[Justin Gruenberg]

  • 解决了问题#6:Z关闭路径的行为。[abcjjy]

1.1 (2013-10-19)

  • 带有负指数的浮点数再次工作。

  • 新的令牌化器大约快20倍。

1.0 (2013-05-28)

  • 解决了问题#2:带有负值且没有空格的路径无法工作。[regebro]

1.0b1 (2013-02-03)

  • 原始发布。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

svg.path-6.3.tar.gz (20.9 kB 查看哈希)

上传时间

构建分发

svg.path-6.3-py2.py3-none-any.whl (16.4 kB 查看哈希)

上传时间 Python 2 Python 3

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面