All formats

JSVG

LanguageJava (Java 8+)
LicenseMIT
Repositorygithub.com/weisJ/jsvg
DocumentationREADME, Javadoc
Depends onnothing (optional JavaFX, SLF4J modules)
Read / writeread (renders to any Graphics2D) / no

JSVG parses SVG and renders it with Java2D. It aims to be small and fast: the README reports about half the memory of svgSalamander and a small fraction of Batik’s. JetBrains IntelliJ IDEA, Apache NetBeans, Eclipse SWT and FlatLaf use it to draw SVG icons.

It covers the static parts of SVG (shapes, paths, text, gradients, patterns, clipping, masks, markers, most filters, CSS) and has partial animation support. It doesn’t run scripts. By default it doesn’t expand XML entities and doesn’t load external resources, which makes it a good choice for untrusted files.

Installation#

Maven:

XML
<dependency>
  <groupId>com.github.weisj</groupId>
  <artifactId>jsvg</artifactId>
  <version>2.2.0</version>
</dependency>

Gradle:

Kotlin
implementation("com.github.weisj:jsvg:2.2.0")

Basic usage: convert SVG to PNG#

Java
import com.github.weisj.jsvg.SVGDocument;
import com.github.weisj.jsvg.parser.SVGLoader;
import com.github.weisj.jsvg.view.FloatSize;

import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class SvgToPng {
    public static void main(String[] args) throws IOException {
        SVGLoader loader = new SVGLoader();
        SVGDocument doc = loader.load(new File("in.svg").toURI().toURL());
        if (doc == null) throw new IOException("cannot parse in.svg");

        FloatSize size = doc.size();
        int w = (int) Math.ceil(size.width), h = (int) Math.ceil(size.height);
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = image.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        doc.render(null, g);
        g.dispose();

        ImageIO.write(image, "png", new File("out.png"));
    }
}

load returns null if the file can’t be parsed.

How to render SVG at a given size#

Pass a ViewBox with the target rectangle; the SVG is scaled to fit it:

Java
import com.github.weisj.jsvg.view.ViewBox;

int outW = 512;
int outH = Math.round(outW * size.height / size.width);
BufferedImage big = new BufferedImage(outW, outH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = big.createGraphics();
doc.render(null, g, new ViewBox(0, 0, outW, outH));
g.dispose();
ImageIO.write(big, "png", new File("out-512.png"));

How to draw an SVG in a Swing component#

Java
import com.github.weisj.jsvg.SVGDocument;
import com.github.weisj.jsvg.view.ViewBox;
import javax.swing.JComponent;
import java.awt.Graphics;
import java.awt.Graphics2D;

class SvgPanel extends JComponent {
    private final SVGDocument document;

    SvgPanel(SVGDocument document) {
        this.document = document;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        document.render(this, (Graphics2D) g, new ViewBox(0, 0, getWidth(), getHeight()));
    }
}

How to load untrusted SVG#

Configure the loader with a LoaderContext. ResourcePolicy.DENY_EXTERNAL blocks references to other files and URLs:

Java
import com.github.weisj.jsvg.parser.LoaderContext;
import com.github.weisj.jsvg.parser.resources.ResourcePolicy;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;

LoaderContext ctx = LoaderContext.builder()
        .externalResourcePolicy(ResourcePolicy.DENY_EXTERNAL)
        .build();
try (InputStream in = Files.newInputStream(Path.of("upload.svg"))) {
    SVGDocument doc = new SVGLoader().load(in, null, ctx);
}

DocumentLimits (via .documentLimits(...)) caps nesting depth and <use> references against denial-of-service files.

How to get the outline of an SVG as a Shape#

Java
java.awt.Shape shape = doc.computeShape();
System.out.println(shape.getBounds2D());

Tips#