How to Save Canvas as an Image With Canvas.Todataurl()

How to save an HTML5 Canvas as an image on a server?

Here is an example of how to achieve what you need:

  1. 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>

Save a canvas image to disk

I finally found a solution! Node apparently supports canvas and allows for saving the image to filesystem via fs.

See here: https://www.youtube.com/watch?v=3c2EFpCr_vY

Saving canvas to image via canvas.toDataURL results in black rectangle

[NOTE]

While this answer is the accepted one, please do read the one by @gman just below, it does contain a way better way of doing.


Your problem is that you are using webGL context, then you need to set the preserveDrawingBuffer property of the webGL context to true in order to be able to call toDataURL() method.

Or alternatively, you can force pixi to use the 2D context, by using the CanvasRenderer Class

Problem with saving canvas as image on server using toDataURL();

Full credit to both @cptnk and @steveola, who between them have led me to the correct answer.

In my case the problem was caused by the fact that toDataURL() does not seem to be able to parse elements that are set to display:none;. So even though you run the necessary Javascript to do the calculations, if it's not rendered in the browser, toDataURL() fails to capture the image data.

My solution was to change my show/hide method from switching the element from a css display:none and display: block to using a position outside the view-port, in my case I am now switching between a top value of 9999 and 0 on the element in question. Feels like a bit of a hack, but it works.

I would imagine that also using things like switching visibility from 0 to 100 would also work (because the image is still rendered, it' just then made transparent), but in my use case, I didn't want the element taking up room in the page and intercepting click events on elements behind it, which it still would with css visibility.

// This show/hide method stops toDataURL(); from capturing the canvas data if it's not visible at the time it's run.
$(document).on('click', '#showreport1link', function(){
$('#chartpreview1').show();
});

// This show/hide method does not.
$(document).on('click', '#showreport1link', function(){
$('#chartpreview1').css('top', '0px'); //was top: 9999; until clicked.
});


Related Topics



Leave a reply



Submit