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.)
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.)
I have just followed Devon's approach with Batik-1.7
However, in order to make it work I had to make the following additions to the hints object:
MyTranscoder transcoder =new MyTranscoder() DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); TranscodingHints hints = new TranscodingHints(); hints.put(ImageTranscoder.KEY_WIDTH, width); // e.g. width=new Float(300) hints.put(ImageTranscoder.KEY_HEIGHT,height);// e.g. height=new Float(75) hints.put(ImageTranscoder.KEY_DOM_IMPLEMENTATION, impl.getDOMImplementation()); hints.put(ImageTranscoder.KEY_DOCUMENT_ELEMENT_NAMESPACE_URI,SVGConstants.SVG_NAMESPACE_URI); hints.put(ImageTranscoder.KEY_DOCUMENT_ELEMENT_NAMESPACE_URI,SVGConstants.SVG_NAMESPACE_URI); hints.put(ImageTranscoder.KEY_DOCUMENT_ELEMENT, SVGConstants.SVG_SVG_TAG); hints.put(ImageTranscoder.KEY_XML_PARSER_VALIDATING, false); transcoder.setTranscodingHints(hints); TranscoderInput ti=new TranscoderInput(uri) transcoder.transcode(ti, null); BufferedImage image = transcoder.getImage();
Seems like something has been updated in batik's XMLAbstractTranscoder( http://svn.apache.org/repos/asf/xmlgraphics/batik/tags/batik-1_7/sources/org/apache/batik/transcoder/XMLAbstractTranscoder.java) with version 1.7.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With