Here is my PHP/mootools HTML5 tutorial to save your canvas on your web server. Click here to view the demo.
On a side note, for the people who read this post, since this demo is using Canvas, this is a level 3 HTML5 implementation, but since we are also using todataurl, and xhr.send, this is a level 4 HTML5 implementation
integration
First let’s prepare everything to make the plugin work, then I’ll explain how the plugin is working.
Note that all the files can be found in this package: download
1.HTML/CSS
As you can see in the file swSaveCanvas.php, we need 3 elements in the HTML for the mootools class swSaveCanvas to work:
-
Element where the progress/status of the upload will be displayed.
-
Button to save (i.e. upload) the canvas
-
1<canvas id="swCanvas" width=320 height=240></canvas>
The Canvas element
2.Javascript
you need to include mootools, swSaveCanvas.js and instantiate a swSaveCanvas object:
1 2 3 4 5 6 7 |
3. PHP
On the server side we need to catch the file, decode it and save it. The decode part is because the js is generating a base64 encoded string and PHP will need to retrieve the binary content of it, here is how you can achieve within a few lines of script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php function decode($tmpname, $filename) { $tmpFile = fopen($tmpname, 'r'); $file = fopen($filename, 'w'); while (!feof($tmpFile)) { fwrite($file, base64_decode(fread($tmpFile, 8192))); } fclose($file); fclose($tmpFile); } $arrfile=$_FILES[0]; $tmpname = $arrfile['tmp_name']; $upload_file = "path/of/the/file.jpg"; if (is_uploaded_file($tmpname)) { decode($tmpname, $upload_file); } ?> |
explanations
How does that work? We are using 2 key mechanism available in HTML5:
- get the data from the canvas: The key part of the swSaveCanvas class is here:
1self.canvasEl.toDataURL('image/'+type)
, that is where we encode the canvas in base64. Once we have this we can build a multipart request according to RFC2388
- send binary content in an ajax request: Now that we have our request we send it using
1XMLHttpRequest.send()
. It works on Firefox 3.6 using send() or sendAsBinary(), but sendAsBinary does not work on Safari. Send works fine with Safari. Chrome does not send the correct data, it sends ASCII instead of binary I guess, and does not understand sendAsBinary. Part from that I also could not have this working on IE (with exCanvas), nor on opera. If anyone has an idea, it is more than welcome!
