Batik Convert SVG to PNG Java Servlet Example

Java Servlet – SVG to PNG


In this example, we will provide a Java servlet program, that takes an user uploaded SVG Image file as input, converts it to PNG Image and returns the file back to the outputstream. We will use Apache Batik library for this conversion, and this tutorial will also reuse some of the components which we have built in SVG to JPG Servlet example.

Select SVG Image to Upload – HTML Form


In this step, we will design a HTML form, that can post uploaded SVG image data to a servlet.We will reuse the same HTML form that we used in SVG to JPG servlet tutorial. So, make sure you grab the HTML form from that example. You will also require the same set of JAR files used in the tutorial before.

Convert SVG Document to InputStream


The first step in the servlet design is to convert the uploaded SVG data into InputStream. We can use Apache Commons IO and Apache Commons FileUpload libraries, to easily transform the uploaded data into InputStream. The code snippet to do this is provided below:
                List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);          
                for (FileItem item : items) {
                        if (item.isFormField()) {                               
                                String fieldname = item.getFieldName();                         
                        } else {
                        //The uploaded file is processed in this section
                        String fieldname = item.getFieldName();
                        String filename = FilenameUtils.getName(item.getName());
                        //We will have the uploaded SVG Image to filecontent object
                        // at this point
                        filecontent = item.getInputStream();                                    
                        }
                }

Create Transcoding Object for Conversion


In this step, we first create TranscoderInput object, by passing the InputStream created in the previous step. We also create a TranscoderOutput object by passing the response.getOutputStream(). The code fragment is provided below:

         //we have obtained the SVG Image to InputStream. We can now convert it into PNG.
         // Read input to TranscoderInput
         TranscoderInput input_svg_image = new TranscoderInput(filecontent);    
         //Output PNG Image points to OutputStream
         TranscoderOutput output_png_image = new TranscoderOutput(out);

Set PNG Image Properties – PNGTranscoder

In this step, we define a PNGTranscoder object that will do the conversion for us. If required, you can set some hints that will specify the final properties of PNG image. (not covered in this tutorial). We will create a simple PNGTranscoder for this example.


         //Create a PNG Transcoder
         PNGTranscoder my_converter = new PNGTranscoder();         


Convert SVG to PNG


In this step, we invoke the transcode method, that will convert the SVG Image to PNG format. We also set the content type of the response which is “image/png” in our case.


         //set response type
         response.setContentType("image/png");
         //return the output PNG image
         my_converter.transcode(input_svg_image, output_png_image);

Full Java Program Example


The full Java servlet program that converts SVG to PNG is provided below:


import java.io.*;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FilenameUtils; 
import java.util.*;
import org.apache.commons.fileupload.servlet.ServletFileUpload; 
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.*;
public class SVG2PNGServlet extends HttpServlet {
public SVG2PNGServlet() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
        OutputStream out = response.getOutputStream();  
        
        try {
                //we will read the SVG File into the input Stream
                InputStream filecontent=null;           
                List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);          
                for (FileItem item : items) {
                        if (item.isFormField()) {                               
                                String fieldname = item.getFieldName();                         
                        } else {
                        //The uploaded file is processed in this section
                        String fieldname = item.getFieldName();
                        String filename = FilenameUtils.getName(item.getName());
                        //We will have the uploaded SVG Image to filecontent object
                        // at this point
                        filecontent = item.getInputStream();                                    
                        }
                }
         //we have obtained the SVG Image to InputStream. We can now convert it into PNG.
         // Read input to TranscoderInput
         TranscoderInput input_svg_image = new TranscoderInput(filecontent);    
         //Output PNG Image points to OutputStream
         TranscoderOutput output_png_image = new TranscoderOutput(out);         
         //Create a PNG Transcoder
         PNGTranscoder my_converter = new PNGTranscoder();         
         //set response type
         response.setContentType("image/png");
         //return the output PNG image
         my_converter.transcode(input_svg_image, output_png_image);
        }
        catch (Exception e) {
               System.err.println(e.toString()); 
         }
         finally {
                 out.close();
         }
        
}
public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
        doGet(request, response);
         }
}


That completes a basic SVG to PNG conversion example tutorial using Apache Batik in Java. You can configure the servlet on the same lines as of SVG to JPG servlet tutorial. If you have a question on this tutorial, post it in the comments section of this post. We will have a look.

3 comments:

  1. I followed your code , after execution but there was a bug,
    org.xml.sax.SAXNotSupportedException: Feature: http://xml.org/sax/features/external-general-entities
    at org.apache.crimson.parser.XMLReaderImpl.setFeature(XMLReaderImpl.java:211)
    at org.apache.crimson.jaxp.SAXParserImpl.setFeatures(SAXParserImpl.java:143)
    at org.apache.crimson.jaxp.SAXParserImpl.(SAXParserImpl.java:126)
    at org.apache.crimson.jaxp.SAXParserFactoryImpl.newSAXParserImpl(SAXParserFactoryImpl.java:113)
    at org.apache.crimson.jaxp.SAXParserFactoryImpl.setFeature(SAXParserFactoryImpl.java:141)
    at org.apache.batik.dom.util.SAXDocumentFactory.(SAXDocumentFactory.java:403)
    at org.apache.batik.transcoder.SVGAbstractTranscoder.createDocumentFactory(SVGAbstractTranscoder.java:150)
    at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstractTranscoder.java:108)
    at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstractTranscoder.java:156)
    at com.pactera.jep.service.bizdesigner.utils.SVGConverterUtils.main(SVGConverterUtils.java:78)
    org.apache.batik.transcoder.TranscoderException: null


    code:
    PNGTranscoder transcoder = new PNGTranscoder();
    TranscoderInput input = new TranscoderInput(new FileInputStream("/Users/mac/logs/image.svg"));
    TranscoderOutput output = new TranscoderOutput(new FileOutputStream("/Users/mac/logs/image.png"));

    try {
    transcoder.transcode(input, output);
    } catch (TranscoderException e) {
    System.out.println("error**");
    e.printStackTrace();
    }
    System.out.println("done.");
    System.exit(0);

    ReplyDelete
  2. I followed your code , after execution but there was a bug,
    org.xml.sax.SAXNotSupportedException: Feature: http://xml.org/sax/features/external-general-entities
    at org.apache.crimson.parser.XMLReaderImpl.setFeature(XMLReaderImpl.java:211)
    at org.apache.crimson.jaxp.SAXParserImpl.setFeatures(SAXParserImpl.java:143)
    at org.apache.crimson.jaxp.SAXParserImpl.(SAXParserImpl.java:126)
    at org.apache.crimson.jaxp.SAXParserFactoryImpl.newSAXParserImpl(SAXParserFactoryImpl.java:113)
    at org.apache.crimson.jaxp.SAXParserFactoryImpl.setFeature(SAXParserFactoryImpl.java:141)
    at org.apache.batik.dom.util.SAXDocumentFactory.(SAXDocumentFactory.java:403)
    at org.apache.batik.transcoder.SVGAbstractTranscoder.createDocumentFactory(SVGAbstractTranscoder.java:150)
    at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstractTranscoder.java:108)
    at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstractTranscoder.java:156)
    at com.pactera.jep.service.bizdesigner.utils.SVGConverterUtils.main(SVGConverterUtils.java:78)
    org.apache.batik.transcoder.TranscoderException: null


    code:
    PNGTranscoder transcoder = new PNGTranscoder();
    TranscoderInput input = new TranscoderInput(new FileInputStream("/Users/mac/logs/image.svg"));
    TranscoderOutput output = new TranscoderOutput(new FileOutputStream("/Users/mac/logs/image.png"));

    try {
    transcoder.transcode(input, output);
    } catch (TranscoderException e) {
    System.out.println("error**");
    e.printStackTrace();
    }
    System.out.println("done.");
    System.exit(0);

    ReplyDelete
  3. org.w3c.dom.DOMException: https://s3.ap-south-1.amazonaws.com/western-chart/7b1c6060-2a33-11ee-8e75-036e6bd6d807.svg:
    The attribute "stroke" represents an invalid CSS value ("rgba(55,71,79 ,0.6)").
    Original message:
    The "stroke" property does not support function values.
    at org.apache.batik.css.engine.CSSEngine.getCascadedStyleMap(CSSEngine.java:775)
    at org.apache.batik.css.engine.CSSEngine.getComputedStyle(CSSEngine.java:867)
    at org.apache.batik.bridge.CSSUtilities.getComputedStyle(CSSUtilities.java:81)
    at org.apache.batik.bridge.CSSUtilities.convertDisplay(CSSUtilities.java:563)
    at org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:206)
    at org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:171)
    at org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:219)
    at org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:171)
    at org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:219)
    at org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:171)
    at org.apache.batik.bridge.GVTBuilder.buildGraphicsNode(GVTBuilder.java:219)
    at org.apache.batik.bridge.GVTBuilder.buildComposite(GVTBuilder.java:171)
    at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:82)
    at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstractTranscoder.java:210)
    at org.apache.batik.transcoder.image.ImageTranscoder.transcode(ImageTranscoder.java:92)
    at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstractTranscoder.java:142)
    at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstractTranscoder.java:158)

    ReplyDelete