带你学习SVG文件处理(三)

883 阅读4分钟

在实际的工作中,涉及到了不同格式之间的转换,其中涉及比较多的是解析svg文件,以及svg格式文件转换为PNG,那么今天我们就具体来说一下这两点内容。因为实际的工作是使用Java,以下是几种基于Java 的常见SVG格式转换方法。

基本介绍

Apache Batik

Batik 是一个开源的 SVG 工具包,可用于将 SVG 文件转换为其他图像格式(如 PNG、JPEG)。该库提供了各种 API 和工具类,可以轻松地将 SVG 文件读取到内存中并转换为所需的格式。

Apache PDFBox

PDFBox 是一个开源的 PDF 工具包,支持将 SVG 文件转换为 PDF。PDF 格式是一种可打印的矢量格式,可以在不同设备上保持高质量的显示效果。

ImageMagick

ImageMagick 是一个功能强大的图像处理库,支持许多图像格式的转换,包括将 SVG 转换为 PNG、JPEG 和 PDF 等格式。虽然 ImageMagick 不是一个 Java 库,但我们可以使用它的命令行工具来执行转换。

String[] command = {"convert", "input.svg", "-resize", "400x400", "output.png"};

Process process = Runtime.getRuntime().exec(command);

process.waitFor();

在上面的示例代码中,我们使用了 ImageMagick 的 convert 命令将 SVG 文件转换为 PNG 格式,并指定输出图像的大小为 400x400。最后我们使用 Java 的 Process 类来执行该命令。

详细介绍

无论您选择哪种方法实现svg的处理,都需要考虑实际的应用场景,选择合适自己的工具和类库,因为在实际的生产环境使用的是Batik,那么接来下我们对他进行一个比较详尽的介绍。

Batik 最初由 W3C(万维网联盟)开发,旨在提供一个基于 Java 的标准 SVG 实现。随着时间的推移,Batik 成为了一个独立的开源项目,并逐渐发展成为一个功能强大的 SVG 工具包。Batik 提供了许多高级特性,如 CSS 样式表支持、动画效果、脚本处理等,使得它成为了处理 SVG 图像的首选工具之一。

以下是 Batik 的主要特点:

1支持各种 SVG 版本:Batik 支持 SVG 1.0、1.1 和 2.0 版本,可以读取和生成这些版本的 SVG 文件。

2完整的 SVG 实现:Batik 实现了 SVG 规范中的大部分特性,包括路径、文本、图形、滤镜、遮罩、混合模式等等。

3高度可定制化:Batik 提供了各种 API 和工具类,可以用于自定义 SVG 解析和渲染过程,以满足各种不同的需求。

4支持各种输出格式:Batik 可以将 SVG 渲染为 PNG、JPEG、TIFF、PDF 和 EPS 等格式,也提供了各种参数设置和选项,用于控制输出图像的质量和大小。

5轻便易用:Batik 的代码体积相对较小,可以很容易地集成到其他 Java 应用程序中使用。

6开源免费:Batik 是一个开源项目,采用 Apache 许可证 2.0 版本,可以自由使用和修改,没有商业限制。

(三)实际生产

1 解析结构

在实际的生产环境中我们只需要引入jar包即可;

<dependency>

    <groupId>org.apache.xmlgraphics</groupId>

    <artifactId>batik-all</artifactId>

    <version>1.16</version>

 </dependency>

我们可以使用Batik解析svg格式文件,获取相应的信息,比如获取宽高信息。代码示例如下:

public static ImageInfo getSvgWidthAndHeight(byte[] data) throws IOException {

        ImageInfo imageInfo = new ImageInfo();

        String parser = XMLResourceDescriptor.getXMLParserClassName();

        SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);

        Document doc = f.createDocument(null, new ByteArrayInputStream(data));

        Element element = doc.getDocumentElement();

        String widthStr = element.getAttribute("width");

        String heightStr = element.getAttribute("height");

             try {

            Integer width  = (int)Double.parseDouble(widthStr);

            Integer height = (int)Double.parseDouble(heightStr);

            imageInfo.setWidth(width);

            imageInfo.setHeight(height);

        } catch (NumberFormatException e) {

                  }

        return imageInfo;

    }

 下面是通过文件链接解析svg格式文件。

/**

     * 解析svg

     * @param svgURI

     * @return

     * @throws Exception

     */

    public static String parseSVG(String svgURI) throws Exception {

        String parser = XMLResourceDescriptor.getXMLParserClassName();

        SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);

        Document doc = f.createDocument(svgURI);

        Element element = doc.getElementById("Layer_1");

        String elementStr = convertElemToSVG(element);

        return elementStr;

    }

2 SVG 文件转换为 PNG 格式

// 创建 SVGDocument

SVGDocument svgDoc = null;

try {

    String parser = XMLResourceDescriptor.getXMLParserClassName();

    SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);

    File file = new File("input.svg");

    svgDoc = f.createSVGDocument(file.toURI().toString());

} catch (Exception ex) {

    ex.printStackTrace();

}

// 创建转换器

PNGTranscoder transcoder = new PNGTranscoder();

// 设置转换器参数

transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, new Float(400));

transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, new Float(400));

// 执行转换

try (OutputStream ostream = new FileOutputStream("output.png")) {

    TranscoderOutput output = new TranscoderOutput(ostream);

    transcoder.transcode(new TranscoderInput(svgDoc), output);

} catch (Exception ex) {

    ex.printStackTrace();

}

在上面的代码示例中,我们首先使用Batik库创建了一个 SVGDocument 对象,并将其从文件中读取到内存中。接着,我们创建了一个 PNGTranscoder 对象以便将 SVG 转换为 PNG。我们还设置了转换器的参数,指定输出图像的宽度和高度。最后,我们执行转换并将结果保存为 PNG 文件。

上面是在实际生产使用的场景,当然Batik库的作用远不止如此,我们还可以实现诸如: SVG 绘制动态图表,实现动画效果等等内容,如果大家用到了这些功能,可以深入的研究使用。