【问题标题】:Saving SVG DOM structure as SVG file using Batik使用 Batik 将 SVG DOM 结构保存为 SVG 文件
【发布时间】:2018-07-02 18:31:56
【问题描述】:

我在 Java 中使用 batik 动态创建和修改 SVG DOM 结构。 我可以在JSVGCanvas 上显示创建的结构。 处理完成后,我想导出这个 DOM 结构并将其保存为 SVG 文件。

为了创建 DOM,我使用了这样的东西:

DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
SVGDocument doc = (SVGDocument) impl.createDocument(svgNS, "svg", null);
Element svgRoot = doc.getDocumentElement();
svgRoot.setAttributeNS(null, "width", "300");
svgRoot.setAttributeNS(null, "height", "300");

我可以在此文档中添加内容并将其显示在JSVGCanvas上,使用类似以下代码:

Element rect = doc.createElementNS(signs, "rect");
rect.setAttributeNS(null, "x", "20");
rect.setAttributeNS(null, "y", "50");
rect.setAttributeNS(null, "width", "140");
rect.setAttributeNS(null, "height", "210");
rect.setAttributeNS(svgNS, "fill", "grey");
rect.setAttributeNS(svgNS, "stroke", "black");
svgRoot.appendChild(rect);

JSVGCanvas canvas = new JSVGCanvas();
canvas.setDocumentState(ALWAYS_DYNAMIC);
canvas.setDocument(doc);

代码显示JSVGCanvas 上的文档。

我的最后一步是尝试将文档保存为 SVG 文件。我使用SVGGraphics2D 在线阅读了许多线程并在那里绘图。然后可以使用Writer 导出文件。

SVGGraphics2D graphics = new SVGGraphics2D(doc);


// Finally, stream out SVG to the standard output using UTF-8
// character to byte encoding
boolean useCSS = true; // we want to use CSS style attribute
Writer out;
try {
    out = new OutputStreamWriter(new FileOutputStream(path), "UTF-8");
graphics.stream(out, useCSS);
out.flush();
out.close();
} catch (UnsupportedEncodingException | FileNotFoundException e) {
    e.printStackTrace();
} catch (SVGGraphics2DIOException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

写入的文件缺少我修改后的 DOM 结构,类似于以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN'
'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>

<svg style="stroke-dasharray:none; shape-rendering:auto; font-family:'Dialog'; text-rendering:auto; fill-opacity:1; color-interpolation:auto; color-rendering:auto; font-size:12px; fill:black; stroke:black; image-rendering:auto; stroke-miterlimit:10; stroke-linecap:square; stroke-linejoin:miter; font-style:normal; stroke-width:1; stroke-dashoffset:0; font-weight:normal; stroke-opacity:1;"
xmlns="http://www.w3.org/2000/svg" 
contentScriptType="text/ecmascript" preserveAspectRatio="xMidYMid meet" 
xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify" version="1.0" contentStyleType="text/css">
<!--Generated by the Batik Graphics2D SVG Generator-->
<defs id="genericDefs"/><g/></svg>

有没有办法让SVGGraphics2D 使用我修改后的svgRootdoc。或者有没有其他方法可以保存JSVGCanvas上显示的文档。

【问题讨论】:

    标签: java dom svg batik


    【解决方案1】:

    您可以尝试将文档另存为纯 xml,因为 svg 基本上是 xml。

    // you will need these imports.
    import javax.xml.transform.Result;
    import javax.xml.transform.Source;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerException;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.TransformerFactoryConfigurationError;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    
    // these 4 lines take your document doc and save it as output.svg
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    Result output = new StreamResult(new File("C:\\output.svg"));
    Source input = new DOMSource(doc);
    transformer.transform(input, output);
    

    你可能会得到奇怪的错误:java.lang.NoClassDefFoundError: org/apache/xml/serializer/TreeWalker 解决方法是在你尝试创建 Transformer 实例之前设置一个系统属性,像这样

    System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
    

    【讨论】:

    • 这样可以将其保存为 sag 文件。但是使用这种方法,我生成的 .svg 看起来不像 JSVGCanvas 上显示的 svg。打开文件证实了这一点。文件中的 DOM 树不是画布上的 DOM 树。变压器似乎变形了一点。使用JPEGTransformer 导出它会给我正确的图片。
    【解决方案2】:

    根据this source而不是

    try {
        out = new OutputStreamWriter(new FileOutputStream(path), "UTF-8");
        graphics.stream(out, useCSS);
    }
    

    尝试导出整个文档:

    try (Writer out = new OutputStreamWriter(new FileOutputStream(path), "UTF-8")) {
        graphics.stream(doc.getDocumentElement(), out, useCSS, false);
    }
    

    确保您的矩形 (Element rect) 已添加到根 svg 文档 (SVGDocument doc)

    【讨论】:

      猜你喜欢
      • 2020-07-10
      • 1970-01-01
      • 2014-09-25
      • 2017-11-08
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多