Java中读取SVG路径数据的最简单方法是什么?

5

我想要使用Java解析SVG图像并处理其中的路径,以进行自定义转换。在Java中,最简单的方法是什么,可以仅提取路径数据?我查看了apache xmlgraphics/batik包,但不太清楚如何返回路径类型和参数。有什么建议吗?

1个回答

11

要提取path数据,您可以使用XPath。

假设您有这个SVG,并且想提取所有path数据(来自两个path元素):

<svg>
  <rect x="1" y="1" width="1198" height="598"
        fill="none" stroke="blue" stroke-width="1" />

  <path d="M200,300 Q400,50 600,300 T1000,300"
        fill="none" stroke="red" stroke-width="5"  />
  <g fill="black" >
    <circle cx="200" cy="300" r="10"/>
    <circle cx="600" cy="300" r="10"/>
    <circle cx="1000" cy="300" r="10"/>
  </g>
  <g fill="#888888" >
    <circle cx="400" cy="50" r="10"/>
    <circle cx="800" cy="550" r="10"/>
  </g>
  <path d="M200,300 L400,50 L600,300 L800,550 L1000,300"
        fill="none" stroke="#888888" stroke-width="2" />
</svg>

首先,您需要将XML文件加载为文档:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("image.svg");

然后您可以使用XPath选择所需的节点。以下表达式选择文件中所有path元素中d属性的内容:

String xpathExpression = "//path/@d";

现在我们可以实例化XPath处理器并编译表达式:
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
XPathExpression expression = xpath.compile(xpathExpression);

由于预期结果是一个节点集(两个字符串),我们使用XPathConstants.NODESET作为第二个参数,在SVG文档上评估表达式:

NodeList svgPaths = (NodeList)expression.evaluate(document, XPathConstants.NODESET);

从那里,您可以使用以下方法提取第一组路径数据:

svgPaths.item(0).getNodeValue();

你说得对,我可以简单地使用XPath来解析文件。我想我正在寻找的是能够处理路径数据的东西。在你的第一个示例中,路径数据中有三个SVG命令。我认为应该有一些东西可以使用这些命令创建绘图序列。 - end-user
是的,你可以按照空格进行拆分,然后提取命令。它们具有标准格式。Q代表二次贝塞尔曲线,指定控制点;T是二次贝塞尔曲线,以切线方式延续曲线;M是移动到,L是画直线等等。有些命令需要一对坐标,有些需要两个。你可以在这里了解更多信息:http://www.w3.org/TR/SVG/paths.html,这是我从中提取示例SVG的地方。 - helderdarocha
我知道在哪里可以找到SVG规范。是的,我可以编写解析器来分解路径数据。但我试图避免重新发明轮子。 - end-user
要解析路径数据,可以使用Batik的PathParser。从那里,您可以将值应用于Batik API、java.awt.geom中的GeneralPath和来自Batik的ExtendedGeneralPath,使您能够重新创建路径并进行修改。 - helderdarocha
我们可以通过上述步骤修改属性。但是在修改属性后,我们如何保存呢? - Tara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接