Ok, this one is a little tricky as there isn’t a lot of authoritative and clear information online about how to do this, so I thought it would help to clarify how to do this as it’s a problem I just came across myself and spent a fair amount of time to get this working. Thankfully, this blog post should allow you to just read through it and be able to start converting SVG image to a PNG image in no time.
SVG to PNG Libraries
Firstly let’s look at the core libraries you need to do this. Thankfully there is just the one which is the Apache Batik library which is part of the Apache XML Graphics Project. In summary, Apache Batik is a Java-based toolkit for applications or applets that want to use images in the Scalable Vector Graphics (SVG) format for various purposes, such as display, generation or manipulation.
Now, this is where things start to get a little more challenging. I would recommend downloading the Bin ZIP file from the download link just mentioned. If you take a look around the Maven Repository you’ll notice that there are a lot of different versions which look all very similar, and all of them are generally last updated around 10 years ago. Sure, these things of tools rarely change once built, but this always worries me.
Once you’ve extracted the ZIP, you’re looking for the file titled batik-all-1.12.jar (Note, the version number may differ when you are reading this…) which will be in the folder, /batik-bin-1.12/batik-1.12/lib/batik-all-1.12.jar.
Add that JAR file to your project.
Now you would think that the project developers would have included all of the dependencies already bundled up. But no. And the documentation isn’t clear about all the dependencies which makes life even more difficult.
Dependencies
So, you need a few dependencies to get this up and running.
XML Commons from the Apache Xerces project
Download XML Commons and add the two JAR files to your project called, xml-apis.jar and xml-apis-ext.jar.
XML Graphics Commons from the Apache XML Graphics Project
Yes, this is the same project as where Batik lives, but hey. Download XML Graphics Commons and add the xmlgraphics-commons-2.4.jar file to your project.
Java Code to Convert an SVG into a PNG
Ok, so now we’ve got all the libraries and dependencies added to your project, it’s now time to actually write the code to convert an SVG to a PNG. Use this code as a starting point to get you going;
try { // Use this to Read a Local Path // String svgUriImputLocation = Paths.get("https://www.contradodigital.com/logo.svg").toUri().toURL().toString(); // Read Remote Location for SVG String svgUriImputLocation = "https:// www.contradodigital.com/logo.svg"; TranscoderInput transcoderInput = new TranscoderInput(svgUriImputLocation); // Define OutputStream Location OutputStream outputStream = new FileOutputStream("C:\\Users\\{{Your User Name on Windows}}\\Documents\\logoAsPngFile.png"); TranscoderOutput transcoderOutput = new TranscoderOutput(outputStream); // Convert SVG to PNG and Save to File System PNGTranscoder pngTranscoder = new PNGTranscoder(); pngTranscoder.transcode(transcoderInput, transcoderOutput); // Clean Up outputStream.flush(); outputStream.close(); } catch (IOException | TranscoderException ex) { System.out.println("Exception Thrown: " + ex); }
Hope that helps to get you going in the right direction if you’re working on a similar problem to this.
I am getting the below error :
Enclosed Exception:
file:filename.svg:
The attribute “style” represents an invalid CSS declaration (“fill: transparent; stroke: rgb(199, 199, 199); stroke-width: 0.5px;”).
Original message:
The “transparent” identifier is not a valid value for the “fill” property.
Hi Biplab,
If I’d have to guess, I’d assume this is something to do with the version of Batik you’re using and/or a combination of the type of SVG you are trying to parse in relation to CSS3 VS CSS2 or CSS.
That is going to be a pain to resolve, good luck. I’ve found the documentation around this to be fairly sparse (hence why I wrote this blog post). So if you do find a solution why this is happening, please do reply to help others in the future.
Regards,
Michael
maybe try inline fill=”#00000000″ as transparent?
My experience attempting to use the Apache Batik library with Android Studio has been unsuccessful. I included the following libraries:
batik-all-1.14.jar
xml-apis.jar
xml-apis-ext.jar
xmlgraphics-commons-2.6.jar
The result is pngTranscoder.transcode throws a TranscoderException with reference to a dead web site.
Hi Bob,
What is the error you’re getting?
Regards
Michael
Error is pngTranscoder.transcode throws a TranscoderException with reference to a dead web site:
org.apache.batik.dom.util.SAXIOException: http://apache.org/xml/features/nonvalidating/load-external-dtd
Hi Bob,
I think you’re missing a few dependencies. The specific error you’re getting is related to this missing dependency ,https://mvnrepository.com/artifact/org.apache.xmlgraphics/batik-dom/1.9
Rather annoyingly when you import the batik-all-1.14.jar file, you (as most others do!) make the assumption that this contains everything you need, because it says the word ‘all’ in. The reality is that if you look at the Maven repo URL for this library, it comes with a bunch of other dependencies, https://mvnrepository.com/artifact/org.apache.xmlgraphics/batik-all/1.14, one of which is the batik-dom JAR file where your error has come from.
When single .jar file libraries require so many dependencies, it soon becomes an absolute nightmare to manage these. In this case, you really need to be utilising tools such as Maven so you don’t have to worry too much about these things (in theory!).
Give that a go, see if that works for you.
Thank you very much for your suggestion. I included the latest version, batik-dom-1.14.jar, but it didn’t help! The exception is:
W/System.err: org.xml.sax.SAXNotRecognizedException: http://apache.org/xml/features/nonvalidating/load-external-dtd
at org.apache.harmony.xml.parsers.SAXParserFactoryImpl.setFeature(SAXParserFactoryImpl.java:93)
at org.apache.batik.dom.util.SAXDocumentFactory.(SAXDocumentFactory.java:405)
at org.apache.batik.transcoder.SVGAbstractTranscoder.createDocumentFactory(SVGAbstractTranscoder.java:152)
at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstractTranscoder.java:108)
at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstractTranscoder.java:158)
You’re getting another dependency issue by the looks of things. Are you using Maven to pull in the batik-all library, or are you manually importing the .jar file into your project?
Further testing yields:
W/System.err: org.xml.sax.SAXNotRecognizedException: http://apache.org/xml/features/nonvalidating/load-external-dtd
W/System.err: at org.apache.harmony.xml.parsers.SAXParserFactoryImpl.setFeature(SAXParserFactoryImpl.java:93)
W/System.err: at org.apache.batik.dom.util.SAXDocumentFactory.(SAXDocumentFactory.java:405)
at org.apache.batik.transcoder.SVGAbstractTranscoder.createDocumentFactory(SVGAbstractTranscoder.java:152)
at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstractTranscoder.java:108)
at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstractTranscoder.java:158)
which can be found at:
https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/org/apache/harmony/xml/parsers/SAXParserFactoryImpl.java#91
public void setFeature(String name, boolean value) throws SAXNotRecognizedException {
…
if (!name.startsWith(“http://xml.org/sax/features/”)) {
throw new SAXNotRecognizedException(name);
I think we’re at the point of diminishing returns for this problem, but I do thank you for your suggestions.
I got this error
org.w3c.dom.DOMException: file:airfield_11.svg:
The attribute “fill” represents an invalid CSS value (“rgba(255,255,255,0.25)”).
Original message:
However a png file was produced
The svg
airfield-11.svg
These are svg’s used in styles for maps, so there are lots, but providing the map software accepts the png (which did provide a tiny aircraft, as expected) hopefully its ok.
I mean… if it works, it works…