Atlaslog / Field Notes / 3D & Cesium
Field note · 3D & Cesium
toDataURL returns a black image, Cesium included
Quick answer
The scene looks right on screen but the exported PNG is black or fully transparent. Either the WebGL drawing buffer was already cleared because preserveDrawingBuffer is off, or cross-origin imagery tainted the canvas.
Symptom
- The export button produces a 1920x1080 pure black PNG.
- Some browsers throw Uncaught DOMException: Failed to execute toDataURL on HTMLCanvasElement: Tainted canvases may not be exported.
- The same capture code works on a page that grabs the frame synchronously.
Checklist
- Call toDataURL directly inside the click handler to separate timing from cross-origin.
- Read the error text: Tainted canvases means CORS, silence means an empty buffer.
- Look for setTimeout, await or requestAnimationFrame between the render and the capture.
- Check whether tile responses carry Access-Control-Allow-Origin.
Fix
Pass contextOptions with webgl preserveDrawingBuffer true and alpha false to the Viewer, or capture inside scene.postRender after requestRender. For tainted canvases add Access-Control-Allow-Origin on the tile server.
Code
Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement':
Tainted canvases may not be exported.var viewer = new Cesium.Viewer('cesiumContainer', {
contextOptions: {
webgl: {
preserveDrawingBuffer: true,
alpha: false
}
}
});
Watch out
- Enabling preserveDrawingBuffer on every page, which costs a buffer copy per frame and extra GPU memory on mobile.
- Screenshotting from a setTimeout without preserveDrawingBuffer, by which point the buffer has already been cleared.
English edition written for Atlaslog from the original Chinese field note. Code is unchanged and runs as-is.
Atlaslog (2026). toDataURL returns a black image, Cesium included. https://www.jingweizhi.com/en/cookbook/cesium-screenshot-black.html (accessed 2026-11-03).