上下文
我正在尝试通过客户端的摄像机捕获快照并将其另存为图像。我有JSFiddle demo。
问题
我没有成功将整个视频区域从Video元素转移到带有Context2D的drawImage
的Canvas。虽然视频是400乘300
<video width="400" height="300" ...
和画布相同400乘300
<canvas width="400" height="300" ...
当我画画时,我指定了300和300的目标...
ctx.drawImage(video, 0, 0, 400, 300, 0, 0, 400, 300);
这是我客户端发生的事情的一个示例。
红色框架元素为video
,绿色元素为canvas
。
我怀疑这是因为视频流不 400乘300(甚至不是4:3的宽高比),但我找不到解决方案,或者至少有一些指示由于视频流,此行为的HTML规范。
有没有人在这方面有更多的经验,可以指出我正确的方向?
很抱歉小提琴中的代码质量不好。
答案 0 :(得分:3)
当您设置HTMLElement的width
和height
属性时,您只需设置其显示大小,而不是其中框架的大小。
Canvas2dContext.drawImage(video, x, y)
将采用帧大小(可以通过强制性getUserMedia
btw设置)。
所以你需要设置你的画布&#39; video.videoWidth
和video.videoHeight
属性的宽度和高度,以获取网络摄像头抓取的完整质量图像,或者通过CSS调用ctx.drawImage(video, 0,0, 400, 300)
将其重新缩放到画布上,或者在getUserMedia
调用期间直接设置必填项(最新版本为navigator.mediaDevices.getUserMedia(video: { width: 300, height:300 });
),但不幸的是,对于最新版本,您无法确定浏览器是否会尊重它,除非通过查看视频.videoHeight /宽度; - )
var ctx = rendering.getContext('2d');
btn.onclick = function() {
switch (select.value) {
case 'css rescale':
rendering.width = 400;
rendering.height = 300;
ctx.drawImage(video, 0, 0, 400, 300);
break;
case 'full quality':
rendering.width = video.videoWidth;
rendering.height = video.videoHeight;
ctx.drawImage(video, 0, 0);
break;
}
}
var initVideo = function(stream) {
video.src = URL.createObjectURL(stream);
video.play();
};
navigator.mediaDevices.getUserMedia({
video: true
})
.then(function(s) {
initVideo(s)
})
.catch(function(err) {
if (err.message.indexOf('secure origins') > -1) {
document.body.innerHTML = '<h3><a target="_blank" href="https://jsfiddle.net/x64ta5r3/">jsfiddle link for chrome and its https policy...</a></h3>(right click -> open Link...';
}
});
&#13;
<button id="btn">take a snapshot</button>
<select id="select">
<option value="css rescale">css rescale</option>
<option value="full quality">full quality</option>
</select>
<video width="400" height="300" id="video"></video>
<canvas id="rendering"></canvas>
&#13;