我试图完成目标以获取某个WebGL Web软件的图像副本:ArcGIS场景查看器。它使用画布,我尝试了这个:
var canvas = document.getElementsByTagName("canvas")[0];
var resultDOM = document.getElementById("result");
resultDOM.innerText = canvas;
var gl = canvas.getContext("webgl", {preserveDrawingBuffer: true});
var pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);
gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
console.log(pixels); // Uint8Array
但是登录控制台的数组总是满[0,0,0,255]。
所以我没有完全控制我用来创建画布的JSAPI,因此我在第一次初始化preserveDrawingBuffer: true
时无法设置canvas
,我所能做的只是在画布加载地图然后执行一些JS。那么我怎样才能得到我需要的图像?
我在这里做错了吗?我也尝试过framebuffer,它也不起作用:
canvas.addEventListener('click', function(ev) {
var gl = canvas.getContext("webgl", {
preserveDrawingBuffer: true
});
var framebuffer = gl.createFramebuffer();
//insert code to get mouse x,y position on canvas
var top = canvas.offsetTop;
var left = canvas.offsetLeft;
var x = ev.clientX - left;
var y = ev.clientY - top;
var pixels = new Uint8Array(4);
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
console.log(x, y, pixels);
});
返回的像素值也是[0,0,0,0]。
您可以尝试以下示例:https://jsfiddle.net/qvtt87ky/ 它总是返回一个完整的黑色图像。
答案 0 :(得分:2)
如果您只需要webgl画布的副本,最简单的方法是将webgl画布绘制到屏幕外画布并使用CanvasRenderingContext2D提取像素数据。
var webglCanvas;
var offscreenCanvas = document.createElement("canvas");
offscreenCanvas.width = webglCanvas.width;
offscreenCanvas.height = webglCanvas.height;
var ctx = offscreenCanvas.getContext("2d");
ctx.drawImage(webglCanvas,0,0);
var imageData = ctx.getImageData(0,0, offscreenCanvas.width, offscreenCanvas.height);
console.log(imageData.data);
imageData.data是一个Uint8ClampedArray,它将包含您要查找的像素数据。
答案 1 :(得分:1)
Framebuffers只是附件的集合。您没有添加任何附件,因此您的帧缓冲区未设置。
最重要的是,如果你想从帧缓冲区中读取内容,你必须将数据放入(渲染到)帧缓冲区。即使您添加了附件,您的示例代码也不会这样做。
示例:
var gl = document.querySelector("canvas").getContext("webgl");
// Clear the canvas to red
gl.clearColor(1, 0, 0, 1); // red
gl.clear(gl.COLOR_BUFFER_BIT);
// Make a framebuffer
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
// Make a texture
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
var width = 1;
var height = 1;
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
// Attach the texture to the framebuffer
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
// Clear the texture to green
gl.clearColor(0, 1, 0, 1); // green
gl.clear(gl.COLOR_BUFFER_BIT);
var pixel = new Uint8Array(4);
// Read from texture (because it's attached to the current
// framebuffer
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
console.log("texture:", pixel);
// Read from canvas to show it's a different color
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
console.log("canvas:", pixel);
<canvas></canvas>
此代码对我没有意义
var resultDOM = document.getElementById("result");
resultDOM.innerText = canvas;
将画布添加为innerText
只意味着它会尝试将HTMLCanvasElement
转换为可能只打印[object HTMLCanvasElement]
之类的字符串,因此我不确定该代码是什么正在努力