General
HTML5: Saving Canvas Image Data and Passing Parameters Using HTML Form And PHP
July 22, 2016
0

This tutorial builds upon the previous tutorial at /2010/10/html5-saving-canvas-image-data-using-php-and-ajax, with additional explanation on how to pass parameters along with the canvas data.

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 type parameter 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.

var canvasData = testCanvas.toDataURL("image/png");

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

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

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:

var testCanvas = document.getElementById("testCanvas");
	var parameter = document.getElementById("parameter").value;
	var canvasData = testCanvas.toDataURL("image/png");
	var postData = "parameter="+parameter+"&canvasData="+canvasData;
	var debugConsole= document.getElementById("debugConsole");
	debugConsole.value=canvasData;

	//alert("canvasData ="+canvasData );
	var ajax = new XMLHttpRequest();
	ajax.open("POST",'testSaveNoRaw.php',true);
	ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");

	ajax.send(postData);

The code above sends out the canvasData as a POST variable. One thing to pay attention here is the
Content-Type is set to application/x-www-form-urlencoded.

If you need to pass parameters, you can do so with variables. The example passes a variable named parameter.  You can easily add more variable with this method.

On the server side, the data will be available in php variable $_POST[“canvasData”] and $_POST[“parameter”].

Important: since Content-Type is set to application/x-www-form-urlencoded,  you need to convert “+” to ” ” (space) on the server side:

$imageData=$_POST['canvasData'];
 $imageData = str_replace(' ','+',$imageData);</pre>
<pre> $filteredData=substr($imageData, strpos($imageData, ",")+1);
 $unencodedData=base64_decode($filteredData);

Below is the full script, testSaveNoRaw.php, which is used in the example.  It saves the canvas and sends back the parameter.

ServerSide

Here’s testSave.php, a basic script that retrieves the raw POST data from the client and saves the data into a file.

<?php
if (isset($_POST["canvasData"]))
{
 $param=$_POST['param'];
 $imageData=$_POST['canvasData'];
 $parameter=$_POST['parameter'];
 $imageData = str_replace(' ','+',$imageData);
 $filteredData=substr($imageData, strpos($imageData, ",")+1);
 $unencodedData=base64_decode($filteredData);

 $filename = 'test.png'
 $file = fopen($filename, 'wb');
 fwrite($file, $unencodedData);
 fclose($file);
 echo "https://www.permadi.com/canvasImages/".$filename."$".$parameter;  
 // echo the filename and parameter, the $ is just an arbitrary separator   between filename and parameter.
}
?>;

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.  Naturally, you can pass parameters to specify user name, filename, or whatever info you need to pass along to process the file as POST variables.
  • 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 somewhere before the html content (weird!):
    <!DOCTYPE html>

Here’s a bare-bone test page: https://www.permadi.com/tutorial/save-canvas/test-no-raw.html