If you are working with HTML5 Canvas element and are looking to save the generated PNG file back on to the server via Java - it is not as easy as saving the byte array. The reason that the generated PNG data is URL encoded and is prefixed with the dataURI format headers.

    var canvas = document.getElementById('#myCanvas');
    var pngData = canvas.toDataURL('image/png');

The following code will convert the raw bytes by stripping off the headers, and coverting the Base64 encoded data to the raw PNG bytes.

private void saveImage(byte[] pngData) {
 String png = new String(pngData);
 String find = "base64%2C";
 String tokens = png.substring(png.indexOf(find) + find.length());
 String decoded = StringUtils.replace(tokens, "%2F", "/");
 byte[] bytes = new Base64Encoder().decode(decoded);

 // save the generated bytes
 // which can then be read in a BufferedImage
 BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
 // mroe code

Hope this helps.

written by Sandeep Gupta

Thursday, July 12, 2012 at 2:10 PM


8 responses to ' Saving HTML5 canvas to Java server '

  • Hi How you doing,

    can you help me on this

    from javascript i am sending canvas data using ajax:

    function saveDataURL(a) {
    var postData = "canvasData="+encodeURIComponent(a);
    var ajax = new XMLHttpRequest();

    in java i have followed your code done this way :

    String png = new String(request.getParameter("canvasData"));
    String find = "base64%2C";
    String tokens = png.substring(png.indexOf(find) + find.length());
    String decoded = StringUtils.replace(tokens, "%2F", "/");
    Base64 decoder = new Base64();
    byte[] imgBytes = decoder.decodeBase64(decoded);
    InputStream in = new ByteArrayInputStream(imgBytes);
    BufferedImage bImageFromConvert = ImageIO.read(in);
    Random rand = new Random();
    File file = new File(""+rand+"yourImage.png");
    ImageIO.write(bImageFromConvert, "png", file);

    But its always giving me this error
    java.lang.IllegalArgumentException: im == null!
    at javax.imageio.ImageIO.write(ImageIO.java:1457)
    at javax.imageio.ImageIO.write(ImageIO.java:1521)
    at com.app.videoediting.videoupload.UploadImage.doPost(UploadImage.java:58)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.ha.tcp.ReplicationValve.invoke(ReplicationValve.java:333)
    at org.apache.catalina.ha.session.JvmRouteBinderValve.invoke(JvmRouteBinderValve.java:219)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:279)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)\

    can you help me as i need to complete this, any kind of help much appreciated

  • i really like that you are giving information on core and advance java concepts. Being enrolled at http://www.wiziq.com/course/1779-core-and-advance-java-concepts i found your information very helpful indeed.thanks for it.

  • Hi!!

    Is there some problem with concurrent use of ImageIO.read() or ImageIO.write()?? I can't find any information about ImageIO thread-safety!!

  • @Optimus: Per the ImageIO technical specifications, thread-safety is a non-goal for them. Refer http://docs.oracle.com/javase/6/docs/technotes/guides/imageio/spec/goals.fm2.html for more details.

    There are however other Java libraries available for image reading/writing/manipulation that are completely thread safe.

  • So, given that, we can't rely on using your code on a web application, given that it's sure it'll be concurrent, right? Or am I losing something?

  • @Optimus: As I mentioned, thread-safety is a non-goal. It may or may not happen.

    I have successfully used the ImageIO class for creating thumbnails (thus involving reading and writing both) in a multi-threaded environment with millions of images. Never faced any thread safety issue.

    Your mileage may vary.

    Have you been facing any issues?

  • No, no...it's only I'm finding a way for validating the image received. ImageIO is perfect for this, but I need a thread-safe API, I don't feel good if I have a serious problem than can or cannot happen...

  • @Optimus: To validate if an image is correct or not, you may either test it in a synchronized block if there are not too many requests coming.

    Second, you can store it temporarily, push it to a queue where a single thread keeps validating image, and then moving them to permanent storage.

    Third, you can try without synchronizing and see if you see issues - I haven't seen anything in my experience.

    Fourth, if you are on Google App Engine or have support, you may use their libraries to check. I have done this personally to reduce latencies as we create thumbnails from public images.

    Lastly, you may use libraries like Sanselan (https://github.com/apache/sanselan) or Scalr(http://www.thebuzzmedia.com/software/imgscalr-java-image-scaling-library/ - suggested if you also need to create thumbnails for later viewing), JAI (http://jaitools.org)

Post Comments