admin管理员组

文章数量:1426388

I am using a website called cesium which shows me a globe of the world, it uses html5. Basically I want to save everything I see on the screen, I am new to html5/javascript...

Everytime I tried to save the canvas it kept showing me a blank black screen. I thought this maybe because the canvas has not finished loading so I put it inside an onload function. Also tried using a timer to sleep the script from saving until after it loads.

window.onload = function(){
    var scene = viewer.scene;
    var canvas = scene.canvas;
    var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); 
    window.location.href=image;
}

I also read it could be something related to CORS (cross origin resource sharing) but I am not getting any errors. Sorry I know this has been asked, but I am new to html5 and the other solutions did not help me.

edit:

Thanks for your help, as I am new to this I took a lot of time trying to understand it, even got a response on the cesium forum. I was hoping you could help me understand the issue some more..

require(['Cesium'], function(Cesium) {
    "use strict";

    // Cesium.CesiumWidget is similar to Cesium.Viewer, but
    // is trimmed down.  It is just a widget for the 3D globe;
    // it does not include the animation, imagery selection,
    // and other widgets, nor does it depend on the third-party
    // Knockout library.
    var widget = new Cesium.CesiumWidget('cesiumContainer',
        {
        contextOptions:{webgl:{preserveDrawingBuffer : true}
                           }});
    var scene = widget.scene;   

    var canvas = scene.canvas;
    var dataUrl = canvas.toDataURL("image/png");
    window.open(dataUrl,'Screenshot','toolbar=yes,location=yes,directories=yes,status=yes,menubar=yes,scrollbars=yes,copyhistory=yes, resizable=yes');
    Sandcastle.finishedLoading();
});

this is my code, I set the preserveDrawingBuffer to true but I still get a blank image, the cesium forum told me this

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);

I am using a website called cesium which shows me a globe of the world, it uses html5. Basically I want to save everything I see on the screen, I am new to html5/javascript...

Everytime I tried to save the canvas it kept showing me a blank black screen. I thought this maybe because the canvas has not finished loading so I put it inside an onload function. Also tried using a timer to sleep the script from saving until after it loads.

window.onload = function(){
    var scene = viewer.scene;
    var canvas = scene.canvas;
    var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); 
    window.location.href=image;
}

I also read it could be something related to CORS (cross origin resource sharing) but I am not getting any errors. Sorry I know this has been asked, but I am new to html5 and the other solutions did not help me.

edit:

Thanks for your help, as I am new to this I took a lot of time trying to understand it, even got a response on the cesium forum. I was hoping you could help me understand the issue some more..

require(['Cesium'], function(Cesium) {
    "use strict";

    // Cesium.CesiumWidget is similar to Cesium.Viewer, but
    // is trimmed down.  It is just a widget for the 3D globe;
    // it does not include the animation, imagery selection,
    // and other widgets, nor does it depend on the third-party
    // Knockout library.
    var widget = new Cesium.CesiumWidget('cesiumContainer',
        {
        contextOptions:{webgl:{preserveDrawingBuffer : true}
                           }});
    var scene = widget.scene;   

    var canvas = scene.canvas;
    var dataUrl = canvas.toDataURL("image/png");
    window.open(dataUrl,'Screenshot','toolbar=yes,location=yes,directories=yes,status=yes,menubar=yes,scrollbars=yes,copyhistory=yes, resizable=yes');
    Sandcastle.finishedLoading();
});

this is my code, I set the preserveDrawingBuffer to true but I still get a blank image, the cesium forum told me this

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);
Share Improve this question edited Jul 30, 2014 at 17:05 gallly asked Jul 29, 2014 at 18:19 galllygallly 1,2114 gold badges27 silver badges46 bronze badges 2
  • Isnt cesium implemented in WebGL? If yes, you need first to draw the WebGL screen in the canvas. – wendelbsilva Commented Jul 29, 2014 at 18:33
  • yeah it is, sorry I am not familiar with WebGL either. I will go and try to find out how to do that and ment on if it worked – gallly Commented Jul 29, 2014 at 19:41
Add a ment  | 

2 Answers 2

Reset to default 4

I recognize this question is now old, but I had the same problem and came across the solution. When you initialize your Viewer you can pass in the option to preserveDrawingBuffer directly, like this:

viewer=new Cesium.Viewer('cesiumContainer',{
    contextOptions: {
        webgl:{preserveDrawingBuffer:true}
    }
});

This will give you the behavior you need.

Edit:

You are right, the method toDataURL is a method of canvas, so its independent of the context we are using. The snipped I posted here (I will leave it in the end of the post) I used it to pose the various layer that I have.

I just tested here, and toDataURL only worked fine after setting preserveDrawingBuffer: true.

gl = canvas.getContext("experimental-webgl",{preserveDrawingBuffer:true});

Here's the trick part. Assuming that you cant modified the code and you celsium get the context only once. You can override the variable assigned to the context with a new context but now with this parameter. I havent tried this on celsium yet, but worked it worked in this example.

Unfortunately, I dont have time right now to find where exactly cesium get the context and if it only get once. Although, I was able to track the context 'creation' down to:

this._originalGLContext=i.getContext("webgl",s)||i.getContext("experimental-webgl",s);
this._gl=this._originalGLContext;

Anyway, I hope you have access to the code and can just add the preserveDrawingBuffer parameter.

var dataUrl = document.getElementById("webglCanvas").toDataURL("image/png");
window.open(dataUrl,'Screenshot','toolbar=yes,location=yes,directories=yes,status=yes,menubar=yes,scrollbars=yes,copyhistory=yes, resizable=yes');

本文标签: javascripttrying to save an html5 canvas but its blankStack Overflow