为什么蜡染无法使用 OutputStream 保存 .svg 文件?
Why is batik can't save .svg file using OutputStream?
我想使用 Apache 的 Batik 库处理文件系统中现有的 .svg 文件。我的目标是加载 .svg 文件,在其上绘制一些形状,然后将最终结果保存在文件系统中。
现在我有两个 class。首先 class 能够加载文件 .svg 并在其上绘制形状,但无法保存结果。第二个 class 能够在新的 canvas 上绘制形状并将结果保存在文件系统上。
这是第一个class。我尝试使用 OutputStream 保存最终结果,但它没有用。
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.svggen.SVGGraphics2DIOException;
import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.swing.svg.GVTTreeBuilderAdapter;
import org.apache.batik.swing.svg.GVTTreeBuilderEvent;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.MalformedURLException;
import java.util.concurrent.atomic.AtomicBoolean;
public class RedrawingSVG extends JFrame {
protected AtomicBoolean shown = new AtomicBoolean(false);
public static void main(String[] args) throws MalformedURLException, InterruptedException, FileNotFoundException, UnsupportedEncodingException, SVGGraphics2DIOException {
RedrawingSVG redrawingSVG = new RedrawingSVG();
redrawingSVG.drawSvg();
}
public void drawSvg() throws MalformedURLException, InterruptedException, FileNotFoundException, UnsupportedEncodingException, SVGGraphics2DIOException {
final JSVGCanvas canvas = new JSVGCanvas();
canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC); // to update it
canvas.setURI(new File("/home/ekuntsevich/Downloads/img.svg").toURI().toURL().toString());
canvas.addGVTTreeBuilderListener(new GVTTreeBuilderAdapter() {
public void gvtBuildCompleted(GVTTreeBuilderEvent e) {
synchronized (shown) {
shown.set(true); // No modifications be fore!!
shown.notifyAll();
}
}
});
getContentPane().add(canvas);
setSize(800, 400);
setVisible(true);
synchronized (shown) { // Strictly required to wait
while (shown.get() == false) {
try {
shown.wait(0);
} catch (Exception e) {
}
}
}
Document doc = canvas.getSVGDocument();
SVGGraphics2D svgGenerator = new SVGGraphics2D(doc);
svgGenerator.setPaint(Color.red);
svgGenerator.fill(new Rectangle(100, 100, 1000, 1000));
Element root = doc.getDocumentElement();
svgGenerator.getRoot(root);
Writer out;
try {
OutputStream outputStream = new FileOutputStream(new File("img2.svg"));
out = new OutputStreamWriter(outputStream, "UTF-8");
svgGenerator.stream(out, true);
outputStream.flush();
outputStream.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SVGGraphics2DIOException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这秒class.
import java.awt.Rectangle;
import java.awt.Graphics2D;
import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.IOException;
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.dom.GenericDOMImplementation;
import org.apache.batik.svggen.SVGGraphics2DIOException;
import org.w3c.dom.Document;
import org.w3c.dom.DOMImplementation;
public class TestSVGGen {
public void paint(Graphics2D g2d) {
g2d.setPaint(Color.red);
g2d.fill(new Rectangle(10, 10, 100, 100));
}
public static void main(String[] args) throws IOException {
// Get a DOMImplementation.
DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
// Create an instance of org.w3c.dom.Document.
String svgNS = "http://www.w3.org/2000/svg";
Document document = domImpl.createDocument(svgNS, "svg", null);
// Create an instance of the SVG Generator.
SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
// Ask the test to render into the SVG Graphics2D implementation.
TestSVGGen test = new TestSVGGen();
test.paint(svgGenerator);
// Finally, stream out SVG to the standard output using
// UTF-8 encoding.
boolean useCSS = true; // we want to use CSS style attributes
Writer out;
try {
OutputStream outputStream = new FileOutputStream(new File("img3.svg"));
out = new OutputStreamWriter(outputStream, "UTF-8");
svgGenerator.stream(out, useCSS);
outputStream.flush();
outputStream.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SVGGraphics2DIOException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
最后我想结合这两个 class 的功能。我想要代码:加载 .svg 图像 -> 在此图像上绘制一些东西 -> 将结果保存为文件系统上的 .svg 图像。
我解决了我的问题。我从 class SVGGraphics2D
中查看了方法 stream
的不同签名,发现有一个方法的参数适合我的情况。我使用下一个方法 stream(Element svgRoot, Writer writer)
来保存 .svg 图像。最后,我使用了 svgGenerator.stream(root, out);
而不是 svgGenerator.stream(out, true);
。它对我有用。
将 SVGDOcument 保存到文件的最快方法 [为了后代 :)]
public static void saveSvgDocumentToFile(SVGDocument document, File file)
throws FileNotFoundException, IOException {
SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
try (Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
svgGenerator.stream(document.getDocumentElement(), out);
}
}
我想使用 Apache 的 Batik 库处理文件系统中现有的 .svg 文件。我的目标是加载 .svg 文件,在其上绘制一些形状,然后将最终结果保存在文件系统中。
现在我有两个 class。首先 class 能够加载文件 .svg 并在其上绘制形状,但无法保存结果。第二个 class 能够在新的 canvas 上绘制形状并将结果保存在文件系统上。
这是第一个class。我尝试使用 OutputStream 保存最终结果,但它没有用。
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.svggen.SVGGraphics2DIOException;
import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.swing.svg.GVTTreeBuilderAdapter;
import org.apache.batik.swing.svg.GVTTreeBuilderEvent;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.MalformedURLException;
import java.util.concurrent.atomic.AtomicBoolean;
public class RedrawingSVG extends JFrame {
protected AtomicBoolean shown = new AtomicBoolean(false);
public static void main(String[] args) throws MalformedURLException, InterruptedException, FileNotFoundException, UnsupportedEncodingException, SVGGraphics2DIOException {
RedrawingSVG redrawingSVG = new RedrawingSVG();
redrawingSVG.drawSvg();
}
public void drawSvg() throws MalformedURLException, InterruptedException, FileNotFoundException, UnsupportedEncodingException, SVGGraphics2DIOException {
final JSVGCanvas canvas = new JSVGCanvas();
canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC); // to update it
canvas.setURI(new File("/home/ekuntsevich/Downloads/img.svg").toURI().toURL().toString());
canvas.addGVTTreeBuilderListener(new GVTTreeBuilderAdapter() {
public void gvtBuildCompleted(GVTTreeBuilderEvent e) {
synchronized (shown) {
shown.set(true); // No modifications be fore!!
shown.notifyAll();
}
}
});
getContentPane().add(canvas);
setSize(800, 400);
setVisible(true);
synchronized (shown) { // Strictly required to wait
while (shown.get() == false) {
try {
shown.wait(0);
} catch (Exception e) {
}
}
}
Document doc = canvas.getSVGDocument();
SVGGraphics2D svgGenerator = new SVGGraphics2D(doc);
svgGenerator.setPaint(Color.red);
svgGenerator.fill(new Rectangle(100, 100, 1000, 1000));
Element root = doc.getDocumentElement();
svgGenerator.getRoot(root);
Writer out;
try {
OutputStream outputStream = new FileOutputStream(new File("img2.svg"));
out = new OutputStreamWriter(outputStream, "UTF-8");
svgGenerator.stream(out, true);
outputStream.flush();
outputStream.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SVGGraphics2DIOException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这秒class.
import java.awt.Rectangle;
import java.awt.Graphics2D;
import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.IOException;
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.dom.GenericDOMImplementation;
import org.apache.batik.svggen.SVGGraphics2DIOException;
import org.w3c.dom.Document;
import org.w3c.dom.DOMImplementation;
public class TestSVGGen {
public void paint(Graphics2D g2d) {
g2d.setPaint(Color.red);
g2d.fill(new Rectangle(10, 10, 100, 100));
}
public static void main(String[] args) throws IOException {
// Get a DOMImplementation.
DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
// Create an instance of org.w3c.dom.Document.
String svgNS = "http://www.w3.org/2000/svg";
Document document = domImpl.createDocument(svgNS, "svg", null);
// Create an instance of the SVG Generator.
SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
// Ask the test to render into the SVG Graphics2D implementation.
TestSVGGen test = new TestSVGGen();
test.paint(svgGenerator);
// Finally, stream out SVG to the standard output using
// UTF-8 encoding.
boolean useCSS = true; // we want to use CSS style attributes
Writer out;
try {
OutputStream outputStream = new FileOutputStream(new File("img3.svg"));
out = new OutputStreamWriter(outputStream, "UTF-8");
svgGenerator.stream(out, useCSS);
outputStream.flush();
outputStream.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SVGGraphics2DIOException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
最后我想结合这两个 class 的功能。我想要代码:加载 .svg 图像 -> 在此图像上绘制一些东西 -> 将结果保存为文件系统上的 .svg 图像。
我解决了我的问题。我从 class SVGGraphics2D
中查看了方法 stream
的不同签名,发现有一个方法的参数适合我的情况。我使用下一个方法 stream(Element svgRoot, Writer writer)
来保存 .svg 图像。最后,我使用了 svgGenerator.stream(root, out);
而不是 svgGenerator.stream(out, true);
。它对我有用。
将 SVGDOcument 保存到文件的最快方法 [为了后代 :)]
public static void saveSvgDocumentToFile(SVGDocument document, File file)
throws FileNotFoundException, IOException {
SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
try (Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
svgGenerator.stream(document.getDocumentElement(), out);
}
}