简体   繁体   English

使用蜡染将SVG DOM结构另存为SVG文件

[英]Saving SVG DOM structure as SVG file using Batik

I dynamically create and modify a SVG DOM structure using batik in Java. 我使用Java中的蜡染动态创建和修改SVG DOM结构。 I can show the created structure on a JSVGCanvas . 我可以在JSVGCanvas上显示创建的结构。 When the process is finished, I want to export this DOM structure and save it as a SVG file. 完成该过程后,我想导出此DOM结构并将其另存为SVG文件。

To create the DOM I used something like this: 要创建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");

I can add stuff to this document and present it on the JSVGCanvas using something like the following code: 我可以向该文档中添加内容,并使用以下代码将其显示在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);

The code shows the document on the JSVGCanvas . 该代码在JSVGCanvas上显示文档。

My last step is trying to save the document as a SVG file. 我的最后一步是尝试将文档另存为SVG文件。 I read many threads online using SVGGraphics2D and drawing in there. 我使用SVGGraphics2D在线阅读了许多线程并在那里绘图。 The file can then be exported using a Writer . 然后可以使用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();
}

The written file is missing my modified DOM structure and looks like the following code: 写入的文件缺少我修改后的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>

Is there a way how I can make the SVGGraphics2D use my modified svgRoot or doc . 有什么方法可以使SVGGraphics2D使用修改后的svgRootdoc Or is there an other way how to save the document shown on the JSVGCanvas . 或者还有另一种方法来保存JSVGCanvas上显示的文档。

You could try and save the document as plain xml since svg is basically xml. 您可以尝试将文档另存为纯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);

There is a chance you will get strange error: java.lang.NoClassDefFoundError: org/apache/xml/serializer/TreeWalker Solution to that is to set a system property before you try to create instance of Transformer, like this 您有可能会遇到奇怪的错误: java.lang.NoClassDefFoundError: org/apache/xml/serializer/TreeWalker解决方案是在尝试创建Transformer实例之前设置系统属性,如下所示

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

According to this source instead of 根据这个来源而不是

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

Try to export whole document: 尝试导出整个文档:

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

Be sure that your rectangle ( Element rect ) already added to root svg document ( SVGDocument doc ) 确保您的矩形( 元素rect )已添加到svg根文档( SVGDocument doc )中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM