Convert HTML5 Canvas into File to be uploaded?

confile picture confile · Sep 26, 2013 · Viewed 76k times · Source

The standard HTML file upload works as follows:

<g:form method="post" accept-charset="utf-8" enctype="multipart/form-data"  
     name="form" url="someurl">

    <input type="file" name="file" id="file" />

</form>

In my case I loaded an image into a html5 canvas and want to submit it as a file to the server. I can do:

var canvas; // some canvas with an image
var url = canvas.toDataURL();

This gives me a image/png as base64.

How can I send the base64 image to the server the same way it is done with the input type file?

The problem is that the base64 file is not of the same type as the file, which is inside the input type="file".

Can I convert the base64 that the types are the same for the server somehow?

Answer

markE picture markE · Sep 26, 2013

For security reasons, you can't set the value of a file-input element directly.

If you want to use a file-input element:

  1. Create an image from the canvas (as you've done).
  2. Display that image on a new page.
  3. Have the user right-click-save-as to their local drive.
  4. Then they can use your file-input element to upload that newly created file.

Alternatively, you can use Ajax to POST the canvas data:

You asked about blob:

var blobBin = atob(dataURL.split(',')[1]);
var array = [];
for(var i = 0; i < blobBin.length; i++) {
    array.push(blobBin.charCodeAt(i));
}
var file=new Blob([new Uint8Array(array)], {type: 'image/png'});


var formdata = new FormData();
formdata.append("myNewFileName", file);
$.ajax({
   url: "uploadFile.php",
   type: "POST",
   data: formdata,
   processData: false,
   contentType: false,
}).done(function(respond){
  alert(respond);
});

Note: blob is generally supported in the latest browsers.