Oct
30
2010

 

In this tutorial, we will demonstrate methods of saving the content of a HTML5 Canvas object using server side scripting. PHP will be used in this example, but the technique can be applied in other languages as well.

This post requires understanding of Javascript, HTML (especially forms and/or AJAX). PHP is used in the example but the code is fairly simple and can be replicated in other languages.

Here’s The Example

Client Side

To retrieve the image data, use toDataURL(type, quality) method on a Canvas object.

  • the typeparameter is the image format to use: image/png, image/jpeg, etc. Current W3 standard (http://www.w3.org/TR/html5/the-canvas-element.html#dom-canvas-todataurl) says that only PNG is required for browsers to conform to HTML 5 spec, so for this example, I’ll only be using PNG.
  • the quality parameter is a number between 0.0 to 1.0 to specify the quality of the image encoding, higher number means better quality. If unspecified, the default value will be used. Note: I am having issues when specifying a second parameters in Firefox 3.6, so I’ll leave this parameter unspecified (update: looks like the second parameter is valid if you specify image/jpg, but not valid on image/png).

Here’s an example of the code that receives the canvas data.
[c]
var canvasData = testCanvas.toDataURL("image/png");
[/c]

The content of the canvasData will look like this (shortened and newlines added for aesthetic):

[c]
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAGB
ElEQVR4nO3UMVEEABAEwZNFBiGOeAe8I0LIsIWCDUinuqtOwAZzd3cvd/fhnMvf6wU87u737
p7Ouez93N3nBTwgCnTeWYIMGU6zwwBpkznmSHAlOk8MwSYMp1nhgBTpvPMEGDKdJ4ZAk
yZzjNDgCnTeWYIMGU6zwwBpkznmSHAlOk8MwSYMp1nhgBTpvPMEGDKdJ4ZAkyZzjNDgCn
e10Ue1tvdPZ1z+Xs/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAIB/+gMqleRG3CrxcAAAAABJRU5ErkJggg==
[/c]

The real image data comes after the “,” (comma) sign — meaning everything after the data:,. The data is base64 encoded so you can send it as part a POST variables safely as text (GET is generally not recommended since it has length limitation and images can easily gets large).

In the HTML side, let’s use AJAX to send the data:

[c]
var canvasData = testCanvas.toDataURL("image/png");
var ajax = new XMLHttpRequest();
ajax.open("POST",’testSave.php’,false);
ajax.setRequestHeader(‘Content-Type’, ‘application/upload’);
ajax.send(canvasData );
[/c]

The code above sends out the canvasDataas a raw POST variable. One thing to pay attention here is the
Content-Type should NOT be set to application/x-www-form-urlencoded but something unknown because basically we want the browser to send the data in its raw state.

This raw data will be available in php variable $GLOBALS["HTTP_RAW_POST_DATA"]. This code calls a .php scripa named testSave.php — this script is explained below.

ServerSide

Here’s testSave.php, a basic script that retrieves the raw POST data from the client and saves the data into a file.
[c]
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];

// Remove the headers (data:,) part.
// A real application should use them according to needs such as to check image type
$filteredData=substr($imageData, strpos($imageData, ",")+1);

// Need to decode before saving since the data we received is already base64 encoded
$unencodedData=base64_decode($filteredData);

//echo "unencodedData".$unencodedData;

// Save file. This example uses a hard coded filename for testing,
// but a real application can specify filename in POST variable
$fp = fopen( ‘test.png’, ‘wb’ );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
[/c]

Notes

  • We are assuming that the file is always a PNG although you can easily check for file type by examining the portion before the comma.
  • The data is base64 encoded so we need to decode it (in PHP, you can just use base64_decode() function to do that, other languages should have similar function since this is a common operation). Then it’s just a matter of saving the decoded data into a file.
  • In this example, to simplify the code, the data is always saved to a file named test.png.
  • A common debugging issue is the file is not written because the script does not have the permission to write file. If you’re encountering issue, check that first, perhaps by writing a basic script to write a dummy file.
  • Note: In Internet Explorer 9 (Beta), you must have this line somehwhere before the html content (weird!):
    [c]
    <!DOCTYPE html>
    [/c]

Here’s a bare-bone test page: http://www.permadi.com/tutorial//tutorial/save-canvas/test-save-html5-canvas.html

The example were tested on Firefox 3.6 (Windows), Chrome 7.0.517.41 (Windows), Internet Explorer 9 (Windows), Safari 4.04.4 (Mac), Chrome 7.0.517.41 (Mac).


Here is another example that automatically downloads the saved file via the browser Downloader:
http://www.permadi.com/tutorial/save-canvas/test-download-html5-canvas.html

14 Responses to “HTML5: Saving Canvas Image Data Using PHP And Ajax”

  1. [...] Posts From Permadi.com:HTML5: Saving Canvas Image Data Using PHP And AjaxUsing HTML 5 Canvas To Draw Over A Web Page – Part 1Using HTML 5 Canvas To Draw Over A Web Page – [...]

  2. HTML5: Saving Canvas Image Data Using PHP And Ajax…

    I found your entry interesting do I’ve added a Trackback to it on my weblog :)

  3. thanks. i was looking for this.

    and for the weird thing in IE, it’s called quirks mode http://en.wikipedia.org/wiki/Quirks_mode

  4. Tanks this post, very help me!

  5. image is sent and saved via ajax, but everytime it overwrites earlier canvas drawing. What if I want it to store every (new)canvas drawing?

  6. This can be handled in the server side coding by checking existing filenames or prompting user for filenames — a different subject which is beyond the scope of the tutorial.

  7. [...] Saving a canvas image [...]

  8. [...] http://www.permadi.com/blog/2010/10/html5-saving-canvas-image-data-using-php-and-ajax/#viewSource [...]

  9. [...] Permadi presents a technique using PHP and AJAX that is exactly what I need. After some tweaking here’s what I came up with. [...]

  10. hello,

    I thank you for this very useful script. I want you to just one question: I can save the file test.png on my server, but can not display the link in the “responseText”.
    Could you help me understand where I’m wrong?
    The following will send the link of my file
    http://ilterzomillennio.com/canvas/prova3.html

    Thank you in advance

    Francesco

  11. In can’t see your PHP file, so I can’t say what’s missing. The filename is “echo”-ed by the PHP script which you should be able to get in the AJAX callback.

  12. [...] In this tutorial, we will demonstrate methods of saving the content of a HTML5 Canvas object using server side scripting. PHP will be used in this example, but the technique can be applied in other languages as well. This post requires understanding of Javascript, HTML (especially forms and/or AJAX). PHP is used in the example but the code is fairly simple and can be replicated in other languages. HTML5: Saving Canvas Image Data Using PHP And Ajax [...]

  13. It doesn’t work at all for me, the image is totally empty, it saves it but nothing more

  14. You need to check what data is being sent to your PHP. In PHP, you can also check what you receive from the app by echoing the data.

Leave a Reply

*