5

I have a canvas and I want to upload the canvas context to the server using ajax and php. I want the final output to be an image stored on the server. I have done image uploading using form. But now I want to get the canvas context convert it to image and upload to the server!

So, how can i do that? Any suggestions, algos or solutions are appreciated!

MJQ
  • 1,778
  • 6
  • 34
  • 60
  • possible duplicate of [Uploading 'canvas' image data to the server](http://stackoverflow.com/questions/1590965/uploading-canvas-image-data-to-the-server) –  Aug 07 '12 at 09:47

1 Answers1

11

This blog post aptly describes the method of saving canvases onto the server with AJAX queries, I guess this should be fitting for you.

Basically, you will need a var canvasData = testCanvas.toDataURL("image/png"); to retrieve the canvas' contents in JavaScript. This will be a Base64 encoded string, something like this: data:image/png;base64,fooooooooooobaaaaaaaaaaar==.

The following code will make sure the AJAX query sends the contents to the HTML:

var ajax = new XMLHttpRequest();
ajax.open("POST",'testSave.php',false);
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(canvasData);

On the server, in the PHP script, you will have a key named HTTP_RAW_POST_DATA in the $GLOBALS array, this will contain the data we just fetched.

// Remove the headers (data:,) part.
$filteredData=substr($GLOBALS['HTTP_RAW_POST_DATA'], strpos($GLOBALS['HTTP_RAW_POST_DATA'], ",")+1);

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

$fp = fopen( 'test.png', 'wb' );
fwrite( $fp, $decodedData);
fclose( $fp );

Of course, test.png is the filename you will save. The first line is required to remove the data:image/png;base64, part of the encoded image, so that it can later be decoded by base64_decode(). It's output ($decodedData) will be saved to the file.

Whisperity
  • 3,012
  • 1
  • 19
  • 36
  • 1
    @MJQ [`fopen()`](http://php.net/manual/en/function.fopen.php) takes its `filename` argument, which might be a file path also. So if you change the `test.png` into `somefolder/test.png`, it will save into `somefolder` with the filename of `test.png`. Be careful as this method saves **ALL** files as `test.png`, essentially **overwriting** the previous save. – Whisperity Aug 07 '12 at 10:19
  • 1
    I'd recommend `file_get_contents('php://input')` over `HTTP_RAW_POST_DATA`, IIRC the latter is not always populated. – deceze Aug 07 '12 at 10:21
  • @MJQ Happy to be able to help. :) Also, take the comment of @deceze into consideration too. You will need to modify `$GLOBALS['HTTP_RAW_POST_DATA']` to a variable like `$initialData` and give value to this variable with a `$initialData = file_get_contents('php://input');` at the **beginning** of the script. Or at least, _before_ the `$filteredData=...` line. – Whisperity Aug 07 '12 at 10:26
  • Your answer was very helpful Whisperity, thanks for that. I just came across a little problem with server side data handling via PHP: I had to set the content-type of my ajax-request to 'application/x-www-form-urlencoded' and everything works as expected. Before doing that my image file was saved but was not able to open properly as an image. – Torsten Barthel Dec 10 '15 at 15:30