上下文
我正在尝试通过客户的摄像机捕获快照并将其保存为图像。我有一个JSFiddle demo .
问题
我没有成功使用 Context2D 的 drawImage
将整个视频区域从 Video 元素获取到 Canvas。虽然视频是 400 x 300
<video width="400" height="300" ...
并且 Canvas 是相同的 400 x 300
<canvas width="400" height="300" ...
当我绘制时,我指定源和目标为 400 x 300...
ctx.drawImage(video, 0, 0, 400, 300, 0, 0, 400, 300);
这是我的客户上发生的情况的示例。
红色框元素是视频
,绿色框元素是 Canvas
。
我怀疑这是因为视频流不是 400 x 300(甚至不是 4:3 宽高比),但我还找不到解决方案,或者至少在HTML 规范表明此行为是由视频流引起的。
有谁在这方面有更多经验并可以为我指明正确的方向吗?
很抱歉 fiddle 中的代码质量较差。
最佳答案
当您设置 HTMLElement 的 width
和 height
属性时,您只是设置其显示尺寸,而不是其内部框架的尺寸。
Canvas2dContext.drawImage(video, x, y)
将获取帧大小(可以通过 getUserMedia
顺便说一句强制设置)。
因此,您需要将 Canvas 的宽度和高度设置为 video.videoWidth
和 video.videoHeight
属性,以获得网络摄像头抓取的完整质量图像,不能调用 ctx.drawImage(video, 0,0, 400, 300) 来在 Canvas 上重新缩放它,因为它是由 CSS 缩放的,或者在 getUserMedia
期间直接设置强制code> 调用(最新规范为 navigator.mediaDevices.getUserMedia(video: { width: 300, height:300 });
),但不幸的是,对于最新版本,您无法确定浏览器会尊重它,除了检查 video.videoHeight/Width ;-)
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...';
}
});
<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>
关于javascript - 使用相机源从视频元素中提取快照,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35698404/