Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a BufferedImage from a SVG?

Tags:

I am using Batik to handle SVG images. Is there any way to get a java.awt.image.BufferedImage from a SVG-file?

I know there are transcoders, with which I could transcode the SVG into, for example, a PNG and then load that PNG with ImageIO.read()· But I don't want to have the temporary file.

like image 801
mr_georg Avatar asked Jul 11 '12 15:07

mr_georg


People also ask

What is a BufferedImage?

A BufferedImage is essentially an Image with an accessible data buffer. It is therefore more efficient to work directly with BufferedImage. A BufferedImage has a ColorModel and a Raster of image data. The ColorModel provides a color interpretation of the image's pixel data.

Can svgs have images?

Scalable Vector Graphics (SVG) is a web-friendly vector file format. As opposed to pixel-based raster files like JPEGs, vector files store images via mathematical formulas based on points and lines on a grid.


2 Answers

Using Batik, something like this:

public static BufferedImage rasterize(File svgFile) throws IOException {      final BufferedImage[] imagePointer = new BufferedImage[1];      // Rendering hints can't be set programatically, so     // we override defaults with a temporary stylesheet.     // These defaults emphasize quality and precision, and     // are more similar to the defaults of other SVG viewers.     // SVG documents can still override these defaults.     String css = "svg {" +             "shape-rendering: geometricPrecision;" +             "text-rendering:  geometricPrecision;" +             "color-rendering: optimizeQuality;" +             "image-rendering: optimizeQuality;" +             "}";     File cssFile = File.createTempFile("batik-default-override-", ".css");     FileUtils.writeStringToFile(cssFile, css);      TranscodingHints transcoderHints = new TranscodingHints();     transcoderHints.put(ImageTranscoder.KEY_XML_PARSER_VALIDATING, Boolean.FALSE);     transcoderHints.put(ImageTranscoder.KEY_DOM_IMPLEMENTATION,             SVGDOMImplementation.getDOMImplementation());     transcoderHints.put(ImageTranscoder.KEY_DOCUMENT_ELEMENT_NAMESPACE_URI,             SVGConstants.SVG_NAMESPACE_URI);     transcoderHints.put(ImageTranscoder.KEY_DOCUMENT_ELEMENT, "svg");     transcoderHints.put(ImageTranscoder.KEY_USER_STYLESHEET_URI, cssFile.toURI().toString());      try {          TranscoderInput input = new TranscoderInput(new FileInputStream(svgFile));          ImageTranscoder t = new ImageTranscoder() {              @Override             public BufferedImage createImage(int w, int h) {                 return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);             }              @Override             public void writeImage(BufferedImage image, TranscoderOutput out)                     throws TranscoderException {                 imagePointer[0] = image;             }         };         t.setTranscodingHints(transcoderHints);         t.transcode(input, null);     }     catch (TranscoderException ex) {         // Requires Java 6         ex.printStackTrace();         throw new IOException("Couldn't convert " + svgFile);     }     finally {         cssFile.delete();     }      return imagePointer[0]; } 
like image 151
elias Avatar answered Oct 12 '22 07:10

elias


A very easy way is to use the TwelveMonkeys lib which adds additional image type support to java's ImageIO

So for example you just add these to your maven (or copy the needed jars):

    <dependency>         <groupId>com.twelvemonkeys.imageio</groupId>         <artifactId>imageio-batik</artifactId> <!-- svg -->         <version>3.2.1</version>     </dependency>     <dependency>         <groupId>batik</groupId>         <artifactId>batik-transcoder</artifactId>         <version>1.6-1</version>     </dependency> 

And then you just read it with

BufferedImage image = ImageIO.read(svg-file); 

To check if the svg reader is registered correctly you could print out the image readers:

Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("SVG"); while (readers.hasNext()) {     System.out.println("reader: " + readers.next()); } 

The lib also supports additional params, see readme on github.

like image 25
Patrick Favre Avatar answered Oct 12 '22 05:10

Patrick Favre