【问题标题】:Parse SVG path style using Batik使用 Batik 解析 SVG 路径样式
【发布时间】:2017-10-20 17:02:19
【问题描述】:

使用 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 我可以想象我可以手动管理自己,但是对于样式来说,如果有一个解析器可以让我直接访问填充和描边值,那就太好了。

【问题讨论】:

    标签: svg java-2d batik


    【解决方案1】:

    Batik 的 API 非常笨拙,我也不得不为此苦苦挣扎。这就是我处理类似问题的方式。

    import org.apache.batik.anim.dom.SVGStylableElement;
    
    private void fill(SVGStylableElement element, String fillValue) {
        element.getStyle().setProperty("fill", fillValue, "");
    }
    

    用法很明显。第一个参数是SVGStylableElement 的一个实例(见下文)。其次是您要设置的颜色值(例如“#FF0000”)。注意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(在您的示例中为“path3622”)。

    我假设您已经以某种方式创建了SVGDocument 的实例,因此我在此省略。 最后但需要的​​方法是 CSS 引擎的初始化。这就是蜡染的魔力。你可以在那里找到更多信息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);
    }
    

    所以记得在创建SVGDocument 的实例之后一次调用这个initializeEngine(...) 方法。如果你不这样做,你会在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>
    

    【讨论】:

      【解决方案2】:

      JavaScript 怎么样?

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

      【讨论】:

      • 我将如何使用 Java 或 Scala 的 Batik API 做到这一点?以及如何从 JS 中获取数据结构?
      • 看起来你可以通过java中的样式索引为: String style = el.getAttribute("style"); int index1 = style.indexOf("fill:#");
      猜你喜欢
      • 1970-01-01
      • 2019-03-12
      • 2014-01-15
      • 2018-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多