使用Batik解析SVG路径样式

时间:2014-01-16 18:44:05

标签: svg java-2d batik

使用Batik,我正在使用Java2D命令将一些SVG代码转换为直接Java / Scala代码。例如,我有以下片段:

<path
  id="path3622"
  transform="translate(0,152.36218)"
  d="m 720,94.5625 c -190.64053,0 -346.23512,150.07433 -355.0625,338.53125 235.63168,-82.12984 472.1202,-97.44221 710.0313,-1.78125 C 1065.2448,243.69491 910.03743,94.5625 720,94.5625 z"
  style="opacity:0.28999999;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
/>

我已使用d=解析了PathHandler位,以生成正确的GeneralPath2D。我将如何解析transformstyle属性? transform我可以想象我可以手工管理自己,但对于风格,使用一个解析器可以直接访问填充和描边值会很棒。

2 个答案:

答案 0 :(得分:1)

Batik有非常笨拙的API,我也不得不挣扎。这就是我遇到类似问题的方法。

import org.apache.batik.anim.dom.SVGStylableElement;

private void fill(SVGStylableElement element, String fillValue) {
    element.getStyle().setProperty("fill", fillValue, "");
}

用法非常明显。第一个参数是SVGStylableElement的实例(见下文)。第二个是您要设置的颜色值(例如&#34;#FF0000&#34;)。请注意,setProperty()还有第三个参数 - 它可用于在CSS中设置!important(我不需要它)。

首先,您需要获取SVGStylableElement的实例。

import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGDocument;

private Optional<SVGStylableElement> getElement(final SVGDocument svg, String id) {
    Element element = svg.getElementById(id);
    if (null == element) {
        return Optional.empty();
    }

    if (!SVGStylableElement.class.isAssignableFrom(element.getClass())) {
        return Optional.empty();
    }

    return Optional.of((SVGStylableElement) element);
}

上述方法采用Java8 +风格,但如果需要,可以为较旧的Java版本重写。您提供了SVGDocument和元素ID的实例(在您的示例中将是&#34; path3622&#34;)。

我假设您已经以某种方式创建了SVGDocument的实例,所以我在这里省略它。 最后但必需的方法是CSS Engine的初始化。这是Batik的神奇之处。您可以在https://wiki.apache.org/xmlgraphics-batik/BootSvgAndCssDom

找到更多信息
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UserAgentAdapter;

private void initializeEngine(SVGDocument svg) {
    UserAgentAdapter userAgent = new UserAgentAdapter();
    DocumentLoader loader = new DocumentLoader(userAgent);
    BridgeContext ctx = new BridgeContext(userAgent, loader);
    ctx.setDynamicState(BridgeContext.DYNAMIC);
    GVTBuilder builder = new GVTBuilder();
    builder.build(ctx, svg);
}

所以请记住在创建initializeEngine(...)实例后立即调用此SVGDocument方法一次。如果您不这样做,则会在element.getStyle()方法的fill(...)中获得NPE。

仅供参考,这些是我使用的pom.xml中的条目:

<dependency>
    <groupId>org.apache.xmlgraphics</groupId>
    <artifactId>batik-svg-dom</artifactId>
    <version>1.9.1</version>
</dependency>
<dependency>
    <groupId>org.apache.xmlgraphics</groupId>
    <artifactId>batik-anim</artifactId>
    <version>1.9.1</version>
</dependency>
<dependency>
    <groupId>org.apache.xmlgraphics</groupId>
    <artifactId>batik-bridge</artifactId>
    <version>1.9.1</version>
</dependency>

答案 1 :(得分:-1)

javascript怎么样?

  var pathFill=path3622.style.fill
  var pathStroke=path3622.style.stroke