Canvas 污染帆布
我正在运行一个mjpeg拖缆,并试图在three.js中将流设置为纹理 我把它写在画布上,然后把画布作为纹理。 但是,我得到一个受污染的画布错误Canvas 污染帆布,canvas,http-headers,cors,webgl,Canvas,Http Headers,Cors,Webgl,我正在运行一个mjpeg拖缆,并试图在three.js中将流设置为纹理 我把它写在画布上,然后把画布作为纹理。 但是,我得到一个受污染的画布错误 DOMException: Failed to execute 'texImage2D' on 'WebGLRenderingContext': Tainted canvases may not be loaded. 我已经在服务器上添加了crossOrigin标头,它的接收方式如下: Access-Control-Allow-Origin:*
DOMException: Failed to execute 'texImage2D' on 'WebGLRenderingContext':
Tainted canvases may not be loaded.
我已经在服务器上添加了crossOrigin标头,它的接收方式如下:
Access-Control-Allow-Origin:*
Content-type:multipart/x-mixed-replace; boundary=--jpgboundary
Date:Tue, 04 Apr 2017 22:27:35 GMT
Server:BaseHTTP/0.3 Python/2.7.9**strong text**
在客户端,我添加了相应的crossOrigin属性
<p>Image to use:</p>
<img id="stream" crossorigin="anonymous"
src="http://192.168.1.224:8080/cam.mjpg">
<p>Canvas:</p>
<canvas id="myCanvas" width="200" height="200" style="border:1px solid
#d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
function updateCanvas() {
var c = document.getElementById("myCanvas");
var ctx2 = c.getContext("2d");
var img = document.getElementById("stream");
img.crossOrigin = "anonymous";
ctx2.drawImage(img, 0, 0);
}
我看不出你的代码不起作用的任何原因。设置
img.crossOrigin
没有意义,因为您的示例中已经下载了图像
用imgur提供的图像进行尝试,效果很好。这表明问题出在您的服务器上
函数updateCanvas(){
var c=document.getElementById(“myCanvas”);
var ctx2=c.getContext(“2d”);
var img=document.getElementById(“流”);
ctx2.drawImage(img,0,0);
试一试{
const d=c.toDataURL();
日志(“画布不脏,收到CORS权限,可以在WebGL中使用”);
}捕获(e){
日志(“画布脏了,没有CORS权限,它*不能*在WebGL中使用”);
}
}
函数日志(…args){
const elem=document.createElement(“pre”);
elem.textContent=[…args].join(“\n”);
文件.正文.附件(elem);
}
document.getElementById(“流”).addEventListener('click',updateCanvas)代码>
img,canvas{width:32px;}
p{margin:0;}
单击图像:
画布:
这是一个chrome错误:
我必须在本地主机上设置一个ffserver+mjpeg代理来确认这一点,但是,
chrome不会在您的运动jpeg流请求中保留crossOrigin头…
Firefox没有这个bug,我也没有找到可靠的前端解决方案
实际上,我发现的唯一解决方法是使用代理,这对于mjpeg streams来说并不容易,但基于express js的代理确实可以很好地工作
但是,还要注意,浏览器应该只在画布上绘制mjpeg流的第一帧[],chrome在这里也有一个bug,不要依赖它,因为它可能很快就会失败,当他们修复它时
编辑
webgl的texImage2d
在动画图像方面似乎与drawImage
不一样
因此,对于您的情况,甚至不要穿过2D画布。您可以直接在
标记中使用mjpeg流,并将其用作更新纹理。
(尽管您仍然需要使用chrome的代理)我不是在src之前设置crossOrigin属性吗?后来我还在代码中反复调用updateCanvas来更新下一帧。@gman,你知道gl.texImage2D
在
中的动画媒体上是否与context2d.drawImage()
一样?texImage2D
比drawImage
更严格drawImage
可以在没有CORS许可的情况下拍摄跨域图像。这样做会将画布标记为脏的texImage2D
未经许可,不会拍摄跨域图像。WebGL画布永远不会变脏,因为在没有CORS权限的情况下,您不能使用跨域图像。@gman,很抱歉,我在您的答案上添加了一条评论,从而分割了讨论。如果用于纹理的2d画布之前已被污染,则TexaImage2D将无法正常工作?那么这可能是OP的问题了。但我的问题是他甚至需要穿过2d画布吗?与drawImage不同,texImage2d能否处理动画图像?正确,通过画布传递跨域非CORS权限的视频将不起作用。穿过画布除了可以让你在上传到纹理之前缩放视频外,什么都不做。你可以用。虽然最近有
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(70, width / height, 1, 1000);
camera.position.z = 500;
scene.add(camera);
window.setTimeout("updateCanvas()", 1000); //start with a delay
texture = new THREE.Texture(canvas);
var material = new THREE.MeshBasicMaterial({ map: texture });
geometry = new THREE.BoxGeometry( 200, 200, 200 );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
canvas.width = canvas.height = size;
renderer.setClearColor(0xeeeeee, 1);
}
function animate() {
requestAnimationFrame(animate);
updateCanvas();
texture.needsUpdate = true;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}