1

I want to save the html canvas as image with a button.

I tried this code but it doesn't work.

<script>
const c= document.getElementById('canvas');
const download = document.getElementById('download');

download.addEventListener('click', function(e) {
console.log(c.toDataURL());
var link = document.createElement('a');
link.download = 'download.png';
link.href = c.toDataURL();
link.click();
link.delete;
});
</script>

<button id="download">Download</button>

I also tried code in another question and home page opens in new tab, not save page.

<script>
var saveButton = document.getElementById('download');
save.onclick = function(e) {
var dataUrl = canvas.toDataURL('image/png');
save.href = dataUrl;
};
</script>

<a href id="save" download="canvas.png" target="_blank">save</a>

edit: This code in link works but when I copy the code to my own file it doesn't work. https://dev.to/dailydevtips1/vanilla-javascript-save-canvas-as-an-image-3pfa

Aycan Candar
  • 63
  • 1
  • 9
  • this will help your: https://stackoverflow.com/questions/11112321/how-to-save-canvas-as-png-image – Mustafa Poya Nov 13 '20 at 12:43
  • problem solved https://stackoverflow.com/questions/64878821/interesting-download-error-when-trying-to-download-html-canvas-as-image-with-but – Aycan Candar Nov 24 '20 at 06:42

3 Answers3

2

You can do this all on the front end, but not sure how well supported it is:

see it working on codepen

// Setup diagonal line on canvas
function drawCanvas() {
  var canvas = document.querySelector("#myCanvas");
  var ctx = canvas.getContext("2d");
  ctx.moveTo(0, 0);
  ctx.lineTo(200, 100);
  ctx.stroke();
}

// draw on canvas
drawCanvas();

// Setup download button event listener
document.querySelector('#download').addEventListener('click', ()=> {
  var canvas = document.querySelector("#myCanvas");
  var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
  
  var element = document.createElement('a');
  var filename = 'test.png';
  element.setAttribute('href', image);
  element.setAttribute('download', filename);

  element.click();
})
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"></canvas>
<div>
  <button id="download">Download</button>
</div>

Based on this : Capture HTML Canvas as gif/jpg/png/pdf?

Huw
  • 289
  • 2
  • 4
  • This does the job, thanks. But why do you have this part? ``.replace("image/png", "image/octet-stream")`` – yenren Feb 14 '22 at 09:28
0

by using this plugin: FileSaver.js, write it as below:

<canvas id="canvas-container" width="400" height="280"></canvas>
<button id="download">Save Canvas Image</button>

<script src="FileSaver.js">
var canvas = document.getElementById("canvas-container");
var saveButton = document.getElementById('download');
saveButton.onclick = function(e) {
    // draw to canvas...
    canvas.toBlob(function(blob) {
        saveAs(blob, "pretty image.png");
    });
};
</script>

Mustafa Poya
  • 2,615
  • 5
  • 22
  • 36
0

Try the following code from: Ajax script to Save Canvas Image on Server - https://coursesweb.net/javascript/ajax-save-canvas-image-server

  • The script presented on that page can be used to get canvas image and save it on server, in PNG format.

HTML - JS Code:

<canvas id="cnv1" width="400" height="280"></canvas>
<button id="btn_cnvimg">Save Canvas Image</button>
<div id="ajaxresp">Ajax response</div>
<script>
var cnv = document.getElementById('cnv1');  //Replace 'cnv1' with your canvas ID
var php_file ='save_cnvimg.php';  //address of php file that get and save image on server

/* Ajax Function
 Send "data" to "php", using the method added to "via", and pass response to "callback" function
 data - object with data to send, name:value; ex.: {"name1":"val1", "name2":"2"}
 php - address of the php file where data is send
 via - request method, a string: 'post', or 'get'
 callback - function called to proccess the server response
*/
function ajaxSend(data, php, via, callback) {
  var ob_ajax =  (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');  //XMLHttpRequest object

  //put data from 'data' into a string to be send to 'php'
  var str_data ='';
  for(var k in data) {
    str_data += k +'='+ data[k].replace(/\?/g, '?').replace(/=/g, '=').replace(/&/g, '&').replace(/[ ]+/g, ' ') +'&'
  }
  str_data = str_data.replace(/&$/, '');  //delete ending &

  //send data to php
  ob_ajax.open(via, php, true);
  if(via =='post') ob_ajax.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  ob_ajax.send(str_data);

  //check the state request, if completed, pass the response to callback function
  ob_ajax.onreadystatechange = function(){
    if (ob_ajax.readyState == 4) callback(ob_ajax.responseText);
  }
}

//register click on #btn_cnvimg to get and save image
var btn_cnvimg = document.getElementById('btn_cnvimg');
if(btn_cnvimg) btn_cnvimg.addEventListener('click', function(e){
  var imgname = window.prompt('Set a name for the image.\n- If you set a name that already exists,\n the image will be replaced with current canvas-image\n\nLeave empty to let the script set an unique name.', '');

  if(imgname !== null){
    //set data that will be send with ajaxSend() to php (base64 PNG image-data of the canvas, and image-name)
    var img_data = {'cnvimg':cnv.toDataURL('image/png', 1.0), 'imgname':imgname};

    //send image-data to php file
    ajaxSend(img_data, php_file, 'post', function(resp){
      //show server response in #ajaxresp, if not exist, alert response
      if(document.getElementById('ajaxresp')) document.getElementById('ajaxresp').innerHTML = resp;
      else alert(resp);
    });
  }
});
</script>

Php file that saves the image on server:

<?php
define('UPLOAD_DIR', 'uploads/');  //Upload folder

//get properly base64 image data passed via post in 'cnvimg'
$cnvimg = trim(strip_tags($_POST['cnvimg']));
$cnvimg = str_replace('data:image/png;base64,', '', $cnvimg);
$cnvimg = str_replace(' ', '+', $cnvimg);

//set image name from 'imgname', or unique name set with uniqid()
$imgname = (isset($_POST['imgname']) && !empty(trim($_POST['imgname']))) ? trim(strip_tags($_POST['imgname'])) : uniqid();

//get image data from base64 and save it on server
$data = base64_decode($cnvimg);
$file = UPLOAD_DIR . $imgname .'.png'; 
$success = file_put_contents($file, $data);

//output response (link to image file, or error message)
print $success ? 'Image: <a href="'. $file .'" target="_blank">'. $file .'</a>' : 'Unable to save the file.';
CoursesWeb
  • 4,179
  • 3
  • 21
  • 27