Search code examples
javasvgpngbatik

JAVA : SVG converter to PNG get 'pattern' wrong


I want to convert svg file to png format with batik1.7, my code like :

public static void convertSvgToPng(InputStream in, FileOutputStream fos) {
    try {
        PNGTranscoder t = new PNGTranscoder();
        TranscoderInput input = new TranscoderInput(in);
        TranscoderOutput output = new TranscoderOutput(fos);
        t.transcode(input, output);
        fos.flush();
        fos.close();
    } catch (IOException ex) {
        Logger.getLogger(CreateFile.class.getName()).log(Level.SEVERE, null, ex);
    } catch (TranscoderException ex) {
        Logger.getLogger(CreateFile.class.getName()).log(Level.SEVERE, null, ex);
    }
}

But some image can't convert, and get this wrong :

org.apache.batik.bridge.BridgeException: null:-1
  The URI "#Unnamed_Pattern"
  specified on the element <pattern> is invalidat     org.apache.batik.bridge.SVGPatternElementBridge.extractPatternContent(SVGPatternElementBridge.java:260)
at org.apache.batik.bridge.SVGPatternElementBridge.createPaint(SVGPatternElementBridge.java:86)
at org.apache.batik.bridge.PaintServer.convertURIPaint(PaintServer.java:359)
at org.apache.batik.bridge.PaintServer.convertPaint(PaintServer.java:259)
at org.apache.batik.bridge.PaintServer.convertFillPaint(PaintServer.java:228)
at org.apache.batik.bridge.PaintServer.convertFillAndStroke(PaintServer.java:146)
at org.apache.batik.bridge.SVGShapeElementBridge.createShapePainter(SVGShapeElementBridge.java:117)
at org.apache.batik.bridge.SVGDecoratedShapeElementBridge.createFillStrokePainter(SVGDecoratedShapeElementBridge.java:58) ....

When I open svg with TXT, there are mang "pattern" tag. After I delete all the "pattern" with a program, convert success, but lose some detall. I think it is not a good way to solve this problem.It have any other way to slove this problem? Please help me.

The problem file :

jsfiddle.net/asdzheng/BtFbX/1/

Solution

  • I have make it work after @BigBadaboom suggestion to use batik-rasterizer.jar replace batik-transcoder.jar. My codes are following :

    import java.io.*;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    import org.apache.batik.apps.rasterizer.DestinationType;
    import org.apache.batik.apps.rasterizer.SVGConverter;
    import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
    import org.apache.batik.util.XMLResourceDescriptor;
    import org.w3c.dom.Document;
    
    
    public class DOMRasterizer {
    
    public Document createDocument(InputStream in) {
        Document doc = null ;
        try {
            // Create a new svg document.
            String parser = XMLResourceDescriptor.getXMLParserClassName();
            SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
            doc = f.createSVGDocument(null, in);
    
        } catch (IOException ex) {
            Logger.getLogger(DOMRasterizer.class.getName()).log(Level.SEVERE, null, ex);
        }
        return doc;
    }
    
    public static void main(String[] args) throws Exception {
    
        DOMRasterizer rasterizer = new DOMRasterizer();
        InputStream in = new FileInputStream(new File("your svg path"));
        Document svgXmlDoc = rasterizer.createDocument(in);
    
        // Save this SVG into a file (required by SVG -> PNG transformation process)
        File svgFile = File.createTempFile("graphic-", ".svg");
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        DOMSource source = new DOMSource(svgXmlDoc);
        FileOutputStream fos = new FileOutputStream(svgFile);
        try {
            transformer.transform(source, new StreamResult(fos));
        } finally {
            fos.close();
        }
        // Convert the SVG into PNG
        File outputFile =new File("output path");
        SVGConverter converter = new SVGConverter();
        converter.setDestinationType(DestinationType.PNG);
        converter.setSources(new String[]{svgFile.toString()});
        converter.setDst(outputFile);
        converter.execute();
    }
    }
    

    And I have the following JARs :

    • batik-all-1.7.jar

    • commons-io-1.3.1.jar

    • commons-logging-1.0.4.jar

    • xml-apis-ext.jar