trying to save canvas

Noob here to html5. I want to add images and text to cesium and save the canvas but I keep getting a blank black screen. Someone mentioned its because cesium uses webgl, is it possible to save the entire screen to my HDD? Pic/text/geometry. I have been using the datatourl method.

Hi Jacob,

We capture the WebGL canvas on a couple of projects including Doarama. You need to initialize the WebGL context with preserveDrawingBuffer enabled before capturing. This can be done in Cesium like this…

var scene = new Cesium.Scene(canvas, {
webgl : {
preserveDrawingBuffer : true
}
}, creditContainer);

There may also be a way to do this through the widgets but I haven’t looked. Note that only the WebGL canvas will be captured (i.e. not divs floating on top etc).

Chris

Thanks I am trying and using that preservedrawingbuffer but the image is still blank. I tried in sandcastle widget and a Dev environment demo I have.

I got some images to show up by placing the code while WebGL renders but it saved an image each frame. Couldn't find out where to place the method when drawing is compleye

Hi Gents, I'd like to resurrect this question. What I dont understand is how to actually obtain the image once said and done. My javascript and webgl is is fair lower than beginner for understanding webdev.
To be more specific what actually does this code produce. A href to image url that can be used via REST call to retrieve the image from cesium server?

My short term goal is to use Cesium to generate data(images) based on rendering particular camera view points of a certain area that I can use offline. My long term goal is to have a learning system control the camera view but have processing of the camera view point be done outside of javascript and cesium. So I am looking for a way to send data back and forth between Cesium and another program.

Thanks!!

If you’re trying to capture a snapshot of the scene, you can use scene.canvas.toDataURL to generate a data URI image of the canvas.

-Hannah

Thanks for the response. I have used this to generate the URI but what I guess I didnt make clear is how to get the image from the URI with out printing it to the console using the URI in my browers. I am looking for way to have the screen shot (when all said and done) be downloaded on my hardrive. The step that I am unclear about for automating from scene.cancas.toDataURL() to hardrive.
Thanks!

This answer on stack overflow might be helpful: http://stackoverflow.com/a/17407392/6261967

This isn’t a Cesium specific thing because you can do this with all canvases. If the link I pasted above doesn’t answer your question, you may be able to find what you’re looking for by searching on stack overflow for how to save an image from a data URI

-Hannah

Hey all,

I did try to implement this also to get an image from the scene… what I get till now is a big black image from the scene… not the scene how it will look like with a nice 3D view.

I use the suggestion from Hannah also, but no luck till now…

What to do?

I have the same problem...
any solution yet ?

Hi,

we had the same problem some time ago and solved it with the following code snippet: Maybe this will help you.

// configure settings

var targetResolutionScale = 1.0; // for screenshots with higher resolution set to 2.0 or even 3.0

var timeout = 10000; // in ms

var scene = viewer.scene;

if (!scene) {

console.error(“No scene”);

}

// define callback functions

var prepareScreenshot = function(){

var canvas = scene.canvas;

viewer.resolutionScale = targetResolutionScale;

scene.preRender.removeEventListener(prepareScreenshot);

// take snapshot after defined timeout to allow scene update (ie. loading data)

setTimeout(function(){

scene.postRender.addEventListener(takeScreenshot);

}, timeout);

}

var takeScreenshot = function(){

scene.postRender.removeEventListener(takeScreenshot);

var canvas = scene.canvas;

canvas.toBlob(function(blob){

var url = URL.createObjectURL(blob);

downloadURI(url, “snapshot-” + targetResolutionScale.toString() + “x.png”);

// reset resolutionScale

viewer.resolutionScale = 1.0;

});

}

scene.preRender.addEventListener(prepareScreenshot);

function downloadURI(uri, name) {

var link = document.createElement(“a”);

link.download = name;

link.href = uri;

// mimic click on “download button”

document.body.appendChild(link);

link.click();

document.body.removeChild(link);

delete link;

}

Thank you very much, this worked.
only one thing left, that I wish my legends and extra information to be included in the screenshot.

but for now this is great thank you for sharing it

Thanks for the answer jbo023!

Unfortunately if you just render the WebGL canvas to an image, you’ll only get the 3D content. You can’t capture any additional html elements on the page.

Thanks,

Gabby

Gabby,

Any chance jbo023’s solution could be incorportated into Cesium as a new feature. Seems like this question has been asked in the past and previous solutions did not work on all browsers.

Thanks in advance.

Hi Jerrold,

That would indeed be an awesome feature. I opened an issue on GitHub, and contributions are always welcome!

Thanks,

Gabby

This works for me and also solves CORS issues when trying to use canvas.toDataUrl(). Thanks!

I had the same issue. The image looked fine in the chrome debugger but was all black in when I painted the 2d canvas. I wrapped the drawImage in a setTimeout with a duration of 0 and it worked.