我正在尝试从 Canvas 中获取像素 RGBA 数据以进行进一步处理。我认为 Canvas 实际上是一个 Unity 游戏,如果它有所作为的话。
我正在尝试用游戏的 Canvas 来做到这一点 Shakes and Fidget .我用 readPixels来自 context 的方法.
这是我尝试过的:
var example = document.getElementById('#canvas');
var context = example.getContext('webgl2'); // Also doesn't work with: ', {preserveDrawingBuffer: true}'
var pixels = new Uint8Array(context.drawingBufferWidth * context.drawingBufferHeight * 4);
context.readPixels(0, 0, context.drawingBufferWidth, context.drawingBufferHeight, context.RGBA, context.UNSIGNED_BYTE, pixels);
但显然所有像素都是黑色的(显然这不是真的)。
编辑:另外,我想多次读取像素。 谢谢大家的回答。 @Kaiido提供的答案对我来说很完美:)
最佳答案
您只能要求一个 Canvas 上下文一次。如果您将相同的选项传递给 getContext()
,则以下所有请求将返回 null
,或者返回之前创建的相同上下文。
现在,您链接到的页面在创建其上下文时未通过 preserveDrawingBuffer
选项,这意味着要能够从那里获取像素信息,您必须连接在与游戏循环发生的事件循环相同的事件循环中。
幸运的是,这个游戏确实使用了一个简单的 requestAnimationFrame
循环,所以要连接到相同的事件循环,我们需要做的就是将我们的代码也包装在 requestAnimationFrame
中称呼。
由于回调是堆叠的,并且它们确实需要此类回调的下一帧来创建循环,因此我们可以确定我们的调用将在它们之后堆叠。
我现在意识到这可能并不明显,所以我将尝试进一步解释 requestAnimationFrame 的作用,以及我们如何确保我们的回调将在 Unity 的回调之后被调用。
requestAnimationFrame(fn)
将 fn
回调推送到回调堆栈中,这些回调将按照先进先出的顺序同时调用,就在之前浏览器将执行其绘制到屏幕 操作。这种情况偶尔发生一次(通常每秒 60 次),发生在最近的事件循环结束时。
可以将其理解为一种setTimeout(fn , time_remaining_until_next_paint)
,主要区别是保证requestAnimationFrame 回调执行器将在事件结束时被调用循环,因此在其他 js 执行此事件循环之后。
因此,如果我们在调用回调的同一事件循环中调用 requestAnimationFrame(fn)
,我们的假 time_remaining_until_next_paint
将是 0
和 fn
将被压入堆栈底部(后进后出)。
当从回调执行器内部调用 requestAnimationFrame(fn)
时,time_remaining_until_next_paint
大约是 16
,而 fn
将在下一帧的第一批中被调用。
因此,从 requestAnimationFrame 的回调执行器外部对 requestAnimationFrame(fn)
的任何调用都保证在与 相同的事件循环中被调用requestAnimationFrame 供电循环,并在之后调用。
所以我们需要获取这些像素,就是将对 readPixels 的调用包装在 requestAnimationFrame 调用中,并在之后调用它Unity 的循环开始了。
var example = document.getElementById('#canvas');
var context = example.getContext('webgl2') || example.getContext('webgl');
var pixels = new Uint8Array(context.drawingBufferWidth * context.drawingBufferHeight * 4);
requestAnimationFrame(() => {
context.readPixels(0, 0, context.drawingBufferWidth, context.drawingBufferHeight, context.RGBA, context.UNSIGNED_BYTE, pixels);
// here `pixels` has the correct data
});
关于javascript - 如何从不属于我的 Canvas 中获取像素数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54047609/