cesium
cesium copied to clipboard
Create one liner to render canvas to image
Create a one liner to render the current canvas to an image.
Requested on the forum here: https://groups.google.com/forum/#!searchin/cesium-dev/webgl%7Csort:date/cesium-dev/FdQk03zgOMI/KAZp4QiPBwAJ
Hello! We will try and complete this as part of 24 Pull Requests London with Codebar.
Thanks @gabriellagal! Let us know if you have any questions =)
Sorry @hpinkos we ended up shifting our focus from it. It was a more advanced problem than we thought - a little above our level at the moment!
No problem =)
Hi, any update about the progress of the issue?
TerriaJS actually builds this right into their Cesium viewer, see the snippet linked to from this forum post:
https://groups.google.com/d/msg/cesium-dev/I-SN1jx0bvg/Vi0h24vFBgAJ
Hi @ggetz! I am happy to take this on. However, it would be very helpful if you could provide some more context for this issue. What specifically is needed to implement a fix?
Bumping this issue since taking screenshots is an important part of the dev process and this seems like it could be useful feature for end users too.
Currently, I am using this snippet; and based on offline discussion, a lot of other CesiumJS developers use a similar approach:
Sandcastle.addToolbarButton("Capture", function() {
const scene = viewer.scene;
const screenshot = function (scene) {
const canvas = scene.canvas;
const fileName = "screenshot";
const link = document.createElement('a');
link.download = fileName + '.png';
canvas.toBlob(function(blob) {
link.href = URL.createObjectURL(blob);
link.click();
});
link.remove();
scene.postRender.removeEventListener(screenshot);
};
scene.postRender.addEventListener(screenshot);
});
This has come up several times on the community forum:
- Cesium Screenshot service/api - November 2020
- how to add gyroscope/compass to cesium viewer? and how to print PDFs or take screenshots? - December 2016
- Implementing a Cesium globe screenshot functionality - October 2015
- export cesium image to png or jpg - screenshot - December 2014
I think adding this to the public API, and potentially integrating it into Sandcastle should be looked into (by way of a keyboard shortcut, for example).
Additionally, this function to take a screenshot could take in parameters to do things like increasing resolution scale, improving shadow quality, screen space error to take high quality screenshots.
From a quick look, it seems like ThreeJS doesn't have an API for this, but Babylon.js has tools to help with screenshots.
This has also been requested in https://community.cesium.com/t/question-about-screenshot-and-model/28940
The basic functionality of registering a postRender
listener and saving the canvas as a blob/URL seems to work. However, at a certain size, the screenshot function just generates a black image. To reproduce this, the sandcastle that was also posted at https://community.cesium.com/t/question-about-screenshot-and-model/28940/18 is replicated here:
https://sandcastle.cesium.com/index.html#c=lVRta9swEP4rwl9qr0FeKIOOvDASChsECs1evhiGIl1sJbIUJNlpN/Lfe7Id8tJkdF8s393zPDrdncSNdp7UErZgyYho2JIpOFmV9Gfji7OIN/bUaM+kBptFySDTmV5WmntpNHGcKRBTtvGVhThYUucJ+Ztp0glTC86oKqDnAYwbdbBBAPEmB8dBh0hHacyTsAXQrjAeMXETTcho3G6zB3Gma+YaeYzT1hx0iMag3kyUWcTxAr/HAoTs1zT9kB7+BSyqPAc72LvanbZnmVJ0e3j29HeuqLBsi4ebVMsl2F9S+OKMXbyb/RVkXvgTulFAlcmxM3P5B4h0JItut7dZFNYiGVw6x+n2WPk1ZiAMr0rQnmJpmYcHBcGKb9jNQSRAqTBbrQwTyMmibyXLga42eRadogoLS0T8eJp1go+LFXCPdlvsUzRXkq/jM6eF0tRw5A1iFmqzvip2dcL6HWTXw6RlSDpdbQCz7pGP9POnvUJb/41x/gm0aJRCDg81lmImnceojQ/D19J2zfcNlQnxL94uXJs504Iz57GJCP9ujFowO6m8Nxo72t0i8twPecbNgJ7er34SpN6pcndN5e5/VO6vqdwn7VMQ9aKh8y8KxvuufJHlxlhPKqtiSlMP5UbhRLh0UfE14MQ5t2/AMD2mDoWsiRSjC88O4Yo5h5FlpVQY/SwaD1PEv6GGWcUb9FiDVewlwIr+eNY6KaXDFM3LTN/W4Ez5FQ
I did spend some time (too much - a few hours, to be honest) trying to figure out why that happens. For the "standalone HTML test" posted at https://community.cesium.com/t/question-about-screenshot-and-model/28940/20 , it is possible to create screenshots that are waaaay larger than the ones that are possible from within CesiumJS. I've been reading about GL context, WebGL, drawing buffers, device limits, but no avail. In other (WebGL) tests, it also seems to bail out at a certain size, but without any error messages or clues about the reasons.
(While diving into some details, the GL context and toBlob
function exposed completely erratic behavior. For example: I could save a ~13000x8000 pixel screenshot. but whether or not that was possible depended on the CSS styling that was used for the cesiumViewer
div
. Yes. Seriously.)
The point is: If the "one-liner" screenshot functionality is added, it should be checked whether this also works when the resolutionScale
is set to a "high" value (like 8 or 10, to create a screenshot in the >10k x 10k size range).