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?
The canvas image needs to be converted to base64 and then from base64 in to binary. This is done using
.toDataURL()
anddataURItoBlob()
It was a pretty fiddly process which required piecing together several SO answers, various blog posts and tutorials.
I've created a tutorial you can follow which walks you through the process.
In response to Ateik's comment here's a fiddle which replicates the original post in case you're having trouble viewing the original link. You can also fork my project here.
There's a lot of code but the core of what I'm doing is take a canvas element:
Set it's context to 2D
Canvas => Base64 => Binary
You could stop at base64 if that's all you need, in my case I needed to convert again to binary so that I could pass the data over to twitter (using OAuth) without use of a db. It turns out you can tweet binary which is pretty cool, twitter will convert it back in to an image.
For security reasons, you can't set the value of a file-input element directly.
If you want to use a file-input element:
Alternatively, you can use Ajax to POST the canvas data:
You asked about blob:
Note: blob is generally supported in the latest browsers.
Currently in spec (very little support as of april '17)
Canvas.toBlob();
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob
EDIT :
The link provides a polyfill (which seems to be slower from the wording), which code is roughtly equivalent to the @pixelomo answer, but with the same api as the native
toBlob
method :To be used this way :
or
Another solution: send the data in var url in a hidden field, decode and save it on the server.
Example in Python Django: