在 Python 中移动、旋转和缩放 SVG 元素

快速回答: 要在 Python 中变换 SVG 元素,请用 SVGDocument 加载 SVG,用选择器或标签名搜索找到目标元素,通过 set_attribute() 设置 transform 属性,然后保存编辑后的 SVG。

1from aspose.svg import SVGDocument
2
3with SVGDocument("document.svg") as document:
4    element = document.root_element.query_selector("#target")
5    if element is not None:
6        element.set_attribute("transform", "translate(20 10) scale(1.2)")
7    document.save("transformed.svg")

在本文中,你将学习如何:

SVG Transform 基础

SVG 变换会改变元素的渲染方式,但不会重写它的原始几何数据。当你需要移动图标、旋转形状、缩放组、重新定位生成的图形,或保留原始坐标但改变可见结果时,这很有用。

在 Aspose.SVG for Python via .NET 中,变换作为 SVG transform 属性值进行编辑。使用 Element.set_attribute() 写入完整的 transform 值,例如 translate(...)rotate(...)scale(...) 或组合的 transform 列表。

常见 transform 函数包括:

Transform 值示例Aspose.SVG API 模式
translate(tx ty)translate(40 12)使用 Element.set_attribute() 写入 transform
rotate(angle)rotate(30)在选中的 SVG 元素上设置 transform
rotate(angle cx cy)rotate(30 190 68)设置带有显式旋转中心的 transform
scale(s)scale(1.2)当 x 和 y 等比缩放时设置 transform
scale(sx sy)scale(1.2 0.8)当 x 和 y 分别缩放时设置 transform
transform 列表translate(20 0) rotate(15)写入一组按顺序执行的完整 transform 操作

如何在 Python 中变换 SVG 元素

当形状应保留原始几何数据,但以新的位置、角度或尺寸渲染时,可以使用这个工作流:

  1. SVGDocument 加载 SVG 文件。
  2. 按 ID、选择器或标签名找到目标元素或组。
  3. 选择 transform 函数,例如 translate()rotate()scale() 或组合 transform 列表。
  4. set_attribute() 设置完整的 transform 属性。
  5. 保存编辑后的 SVG,并确认元素位置符合预期。

本文的代码示例和插图使用示例文件 transform-svg-elements.svg。运行示例时,可将它用作 data/transform-svg-elements.svg

移动 SVG 元素

当你需要移动元素,但不修改它的 xycxcy 或 path data 时,使用 translate(tx ty)。下面的示例找到 #badge 组,将它向左移动 25 个单位并向上移动 25 个单位,然后保存编辑后的 SVG。

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "data/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "transform-svg-elements.svg")
 7output_path = os.path.join(output_folder, "badge-moved.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument(input_path) as document:
11    badge = document.root_element.query_selector("#badge")
12
13    if badge is not None:
14        badge.set_attribute("transform", "translate(-25 -25)")
15
16    document.save(output_path)

代码使用 query_selector() 按 ID 找到组,更新它的 transform 属性,并使用 SVGDocument.save() 写出结果。把 transform 应用到 <g> 元素时,组内所有形状会一起移动。

下图比较源 SVG (a) 与对 #badge 组应用 translate(-25 -25) 后的结果 (b)。

原始 SVG 与应用 translate transform 后移动的 badge 组

围绕指定点旋转 SVG 元素

当元素应围绕自身中心或另一个已知点旋转时,使用 rotate(angle cx cy)。示例围绕原始边界区域中心旋转 #diamond 矩形。

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "data/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "transform-svg-elements.svg")
 7output_path = os.path.join(output_folder, "rectangle-rotated.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument(input_path) as document:
11    diamond = document.root_element.query_selector("#diamond")
12
13    if diamond is not None:
14        diamond.set_attribute("transform", "rotate(45 195 60)")
15
16    document.save(output_path)

rotate(45 195 60) 中的中心点是 transform 值的一部分。如果不指定这个点,SVG 会围绕当前坐标原点旋转元素,这通常会让元素看起来发生了意外位移。

下图显示矩形在旋转前 (a) 以及围绕 rotate(45 195 60) 中定义的点旋转后 (b) 的结果。

原始 SVG 与围绕指定点旋转后的矩形

缩放 SVG 组

当你需要调整元素或组的大小时,使用 scale()。由于缩放会围绕当前原点发生,如果希望缩放后的结果仍位于合适位置,应组合使用 translate()scale()

下面的示例找到 #arrow 组,并设置完整 transform 值:translate(250 70) scale(1.5)。平移把箭头放入 SVG 视口内,缩放让变化更容易看清。

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "data/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "transform-svg-elements.svg")
 7output_path = os.path.join(output_folder, "arrow-scaled.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument(input_path) as document:
11    arrow = document.root_element.query_selector("#arrow")
12
13    if arrow is not None:
14        arrow.set_attribute("transform", "translate(250 70) scale(1.5)")
15
16    document.save(output_path)

此示例有意替换 #arrow 上之前的 transform 值。当你希望输出具有确定的最终位置和大小时,可以使用这种方式。

下图比较源 SVG (a) 与对 #arrow 组应用 translate(250 70) scale(1.5) 后的结果 (b)。

原始 SVG 与应用 translate 和 scale transform 后缩放的箭头组

常见错误和修复

问题可能原因修复
元素旋转后偏移很远使用了不带中心点的 rotate(angle)当旋转应围绕已知点发生时,使用 rotate(angle cx cy)
现有布局意外改变之前的 transform 值被覆盖只有在需要确定的最终 transform 时才替换整个值
缩放导致元素移动缩放相对于当前原点发生有意组合 translate()scale(),并检查 transform 顺序
缩放后的元素出现在视口外transform 中没有合适的平移组合 translate()scale(),让缩放结果保持可见
保存的 SVG 没有变化编辑后没有保存文档更新 transform 后调用 document.save(output_path)
可视结果与 transform 字符串不一致transform 函数按顺序应用测试确切顺序,例如 translate(...) scale(...)scale(...) translate(...)

FAQ

如何在 Python 中移动 SVG 元素?

SVGDocument 加载 SVG,通过 query_selector()get_elements_by_tag_name() 找到元素,设置 element.set_attribute("transform", "translate(40 12)"),然后保存文档。

如何围绕中心旋转 SVG 元素?

设置类似 rotate(45 195 60) 的 transform,其中 45 是角度,195 60 是旋转中心。使用中心点可以避免元素意外围绕 SVG 原点旋转。

如何在 Python 中缩放 SVG 元素?

简单缩放时,把 transform 属性设为 scale(1.5)。如果缩放后的元素还需要停留在指定位置,可使用组合值,例如 translate(250 70) scale(1.5)

如何在 SVG 中组合 translate 和 scale?

设置一个同时包含两种操作的 transform 值,例如 element.set_attribute("transform", "translate(250 70) scale(1.5)")。操作顺序会影响最终渲染结果。

应该修改 x 和 y 属性,还是使用 transform?

对单个形状做简单几何编辑时,可以使用 xycxcy。当你需要移动、旋转、缩放,或在保留原始几何数据的同时改变渲染方式时,使用 transform

相关文章