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>
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
Stopping Gif Animation Programmatically
Restricting Input to Textbox: Allowing Only Numbers and Decimal Point
Double Quotes Within PHP Script Echo
Why Are Inline Event Handler Attributes a Bad Idea in Modern Semantic Html
How to Load Up CSS Files Using JavaScript
Get Element from Within an Iframe
How to Check File Mime Type With JavaScript Before Upload
Jquery Document.Createelement Equivalent
Changing Source on Html5 Video Tag
What Browsers Support Html5 Websocket API
How to Check Whether Google Maps Is Fully Loaded
Disable Pasting Text into HTML Form
How Is the Default Submit Button on an HTML Form Determined
How to Scroll to an Element Using JavaScript
Html5 File API Read as Text and Binary
Get Page Generated With JavaScript in Python