我正在尝试在 javascript 中实现延迟网络摄像头查看器,使用 Three.js 实现 WebGL 功能。
我需要存储从网络摄像头抓取的帧,以便它们可以在一段时间后显示(几毫秒到几秒)。我可以在没有 Three.js 的情况下使用 canvas
和 getImageData()
来做到这一点。你可以找到an example on jsfidle .
我正在尝试寻找一种无需 Canvas 但使用 Three.js Texture
或 DataTexture
对象的方法。 Here an example of what I'm trying .问题是我找不到如何将图像从 Texture
(image
的类型为 HTMLVideoElement
)复制到另一个。
在 rotateFrames()
函数中,旧的帧应该丢失,新的应该替换,就像在 FIFO 中一样。但是线路
frames[i].image = frames[i + 1].image;
只是复制引用,而不是纹理数据。我想 DataTexture
应该这样做,但我无法从 Texture
或 HTMLVideoElement
中获取 DataTexture
>.
有什么想法吗?
警告:您必须有摄像头并允许浏览器使用它才能使示例正常工作。显然,您必须有更新的浏览器。
最佳答案
这是您要找的东西吗??
http://fiddle.jshell.net/m4Bh7/10/
编辑:
function onFrame(dt) {
if (video.readyState === video.HAVE_ENOUGH_DATA) { /* new frame available from webcam */
context.drawImage(video, 0, 0,videoWidth,videoHeight);
frames[framesNum - 1].image.data = new Uint8Array(context.getImageData(0,0,videoWidth, videoHeight).data.buffer);
frames[framesNum - 1].needsUpdate = true;
}
}
这是最重要的部分:它制作帧的副本并将其作为数据保存在 dataTexture 中。
function rotateFrames() {
for (var i = 0; i != framesNum - 1; ++i) {
/*
* FIXME: this does not work!
*/
frames[i].image.data = frames[i + 1].image.data;
frames[i].needsUpdate = true;
}
}
这会将帧中的数据从一个纹理复制到另一个纹理。
新版本:http://fiddle.jshell.net/hWL2E/4/
function onFrame(dt) {
if (video.readyState === video.HAVE_ENOUGH_DATA) { /* new frame available from webcam */
context.drawImage(video, 0, 0,videoWidth,videoHeight);
var frame = new THREE.DataTexture(new Uint8Array(context.getImageData(0,0,videoWidth, videoHeight).data.buffer) ,videoWidth,videoHeight);
frames[framesNum - 1] = frame;
frames[framesNum - 1].needsUpdate = true;
sprites[framesNum - 1].map = frames[framesNum - 1];
}
}
它为视频图像的每一帧生成一个新的纹理。
function rotateFrames() {
for (var i = 0; i != framesNum - 1; ++i) {
/*
* FIXME: this does not work!
*/
frames[i] = frames[i + 1];
sprites[i].map = frames[i];
}
}
这就是让它变得更好的原因。因为它重用了使用过的纹理,意味着它不需要重新发送到 GPU。
关于javascript - Three.js:texture到datatexture,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12586353/