Swing & Batik: Create an ImageIcon from an SVG file?

Electrons_Ahoy picture Electrons_Ahoy · Mar 22, 2010 · Viewed 14.4k times · Source

Simply put, I'm looking for a way to make an ImageIcon from an SVG file using the batik library. I don't want to have to raster the SVG to disk first, I just want to be able to pull an svg out of the jar file and have it land as a UI element.

I feel like this should be reasonably easy, but the batik javadocs aren't telling me what I need to know.

(Why batik? Well, we're already using it, so we don't have to run another library past legal.)

Answer

Devon_C_Miller picture Devon_C_Miller · Mar 22, 2010

It's really quite easy, just not very intuitive.

You need to extend ImageTranscoder. In the createImage method you allocate a BufferedImage, cache it as a member variable, and return it. The writeImage method is empty. And you'll need to add a getter to retrieve the BufferedImage.

It will look something like this:

    class MyTranscoder extends ImageTranscoder {
        private BufferedImage image = null;
        public BufferedImage createImage(int w, int h) {
            image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            return image;
        }
        public void writeImage(BufferedImage img, TranscoderOutput out) {
        }
        public BufferedImage getImage() {
            return image;
        }
    }

Now, to create an image you create an instance of your transcoder and pass it the desired width and height by setting TranscodingHints. Finally you transcode from a TranscoderInput to a null target. Then call the getter on your transcoder to obtain the image.

The call looks something like this:

    MyTranscoder transcoder = new MyTranscoder();
    TranscodingHints hints = new TranscodingHints();
    hints.put(ImageTranscoder.KEY_WIDTH, width);
    hints.put(ImageTranscoder.KEY_HEIGHT, height);
    transcoder.setTranscodingHints(hints);
    transcoder.transcode(new TranscoderInput(url), null);
    BufferedImage image = transcoder.getImage();

Simple, right? (Yeah, right. Only took me 2 weeks to figure that out. Sigh.)