How to save an HTML5 Canvas as an image on a server?
Here is an example of how to achieve what you need:
- Draw something (taken from canvas tutorial)
<canvas id="myCanvas" width="578" height="200"></canvas><script> var canvas = document.getElementById('myCanvas'); var context = canvas.getContext('2d'); // begin custom shape context.beginPath(); context.moveTo(170, 80); context.bezierCurveTo(130, 100, 130, 150, 230, 150); context.bezierCurveTo(250, 180, 320, 180, 340, 150); context.bezierCurveTo(420, 150, 420, 120, 390, 100); context.bezierCurveTo(430, 40, 370, 30, 340, 50); context.bezierCurveTo(320, 5, 250, 20, 250, 50); context.bezierCurveTo(200, 5, 150, 20, 170, 80); // complete custom shape context.closePath(); context.lineWidth = 5; context.fillStyle = '#8ED6FF'; context.fill(); context.strokeStyle = 'blue'; context.stroke();</script>
Convert canvas image to URL format (base64)
var dataURL = canvas.toDataURL();
Send it to your server via Ajax
$.ajax({ type: "POST", url: "script.php", data: { imgBase64: dataURL } }).done(function(o) { console.log('saved'); // If you want the file to be visible in the browser // - please modify the callback in javascript. All you // need is to return the url to the file, you just saved // and than put the image in your browser. });
- Save base64 on your server as an image (here is how to do this in PHP, the same ideas is in every language. Server side in PHP can be found here):
I played with this two weeks ago, it's very simple. The only problem is that all the tutorials just talk about saving the image locally. This is how I did it:
1) I set up a form so I can use a POST method.
2) When the user is done drawing, he can click the "Save" button.
3) When the button is clicked I take the image data and put it into a hidden field. After that I submit the form.
document.getElementById('my_hidden').value = canvas.toDataURL('image/png');document.forms["form1"].submit();
4) When the form is submited I have this small php script:
<?php $upload_dir = somehow_get_upload_dir(); //implement this function yourself$img = $_POST['my_hidden'];$img = str_replace('data:image/png;base64,', '', $img);$img = str_replace(' ', '+', $img);$data = base64_decode($img);$file = $upload_dir."image_name.png";$success = file_put_contents($file, $data);header('Location: '.$_POST['return_url']);?>
I think you should convert the image to base64 and then to Blob and send it to the server. When you use base64 images, a lot of lines will be sent to server. With blob, it's only the file.
You can use this code bellow:
function dataURLtoBlob(dataURL) { let array, binary, i, len; binary = atob(dataURL.split(',')[1]); array = []; i = 0; len = binary.length; while (i < len) { array.push(binary.charCodeAt(i)); i++; } return new Blob([new Uint8Array(array)], { type: 'image/png' });};
And canvas code here:
const canvas = document.getElementById('canvas');const file = dataURLtoBlob( canvas.toDataURL() );
After that you can use ajax with Form:
const fd = new FormData;fd.append('image', file);$.ajax({ type: 'POST', url: '/url-to-save', data: fd, processData: false, contentType: false});
The code in CoffeeScript syntax:
dataURLtoBlob = (dataURL) -> # Decode the dataURL binary = atob(dataURL.split(',')[1]) # Create 8-bit unsigned array array = [] i = 0 while i < binary.length array.push binary.charCodeAt(i) i++ # Return our Blob object new Blob([ new Uint8Array(array) ], type: 'image/png')
And canvas code here:
canvas = document.getElementById('canvas')file = dataURLtoBlob(canvas.toDataURL())
After that you can use ajax with Form:
fd = new FormData# Append our Canvas image file to the form datafd.append 'image', file$.ajax type: 'POST' url: '/url-to-save' data: fd processData: false contentType: false