简体   繁体   English

从带有摄像机源的视频元素中提取快照

[英]Extract snapshot from video element with camera source

Context 语境

I'm trying to capture a snapshot through the client's video camera and save it as an image. 我正在尝试通过客户端的摄像机捕获快照并将其另存为图像。 I have a JSFiddle demo . 我有一个JSFiddle演示

Problem 问题

I'm not succeeding in getting the whole video area from the Video element to the Canvas with Context2D's drawImage . 我没有使用Context2D的drawImage将整个视频区域从Video元素获取到Canvas。 Althought the Video is 400 by 300 虽然视频是400 x 300

<video width="400" height="300" ...

and the canvas is the same 400 by 300 画布是相同的400 x 300

<canvas width="400" height="300" ...

and when I draw I specify for both source and target 400 by 300... 当我绘制时,我将源和目标400都指定为300 ...

ctx.drawImage(video, 0, 0, 400, 300, 0, 0, 400, 300);

This is a sample of what is happening on my client. 这是我的客户正在发生的事情的一个示例。

在此处输入图片说明

The red framed element is the video and the green one is the canvas . 红色框是video ,绿色框是canvas

I suspect this is because the video stream is not 400 by 300 (not even 4:3 aspect ratio), but I couldn't find yet a solution for this or at least some indication in the HTML specs that this behavior is because of the video stream. 我怀疑这是因为视频流不是 400 x 300(甚至不是4:3的宽高比),但是我还没有找到解决方案,或者在HTML规范中至少没有某种迹象表明这种行为是由于视频流。

Does anyone have some more experience in this area and can point me in the right direction? 有谁在这方面有更多的经验,可以指出正确的方向吗?

Sorry for the bad quality of the code in the fiddle. 对不起,小提琴中的代码质量很差。

When you set the HTMLElement's width and height attributes, you're only setting its display size, not the size of the frame inside it. 设置HTMLElement的widthheight属性时,仅设置其显示尺寸,而不设置其内部框架的尺寸。

Canvas2dContext.drawImage(video, x, y) will take the frame size, (which can be set by the mandatory of getUserMedia btw). Canvas2dContext.drawImage(video, x, y)将采用帧大小(可以由getUserMedia btw的强制性设置)。

So you need either to set your canvas' width and height to the video.videoWidth and video.videoHeight properties to get the full quality image grabbed by the webcam, ot to call ctx.drawImage(video, 0,0, 400, 300) to rescale it on the canvas as it is scaled by CSS, or setting directly the mandatory during the getUserMedia call (latests specs are navigator.mediaDevices.getUserMedia(video: { width: 300, height:300 }); ) but unfortunately, for this latest, you can't be sure the browser will honor it, except by checking the video.videoHeight/Width ;-) 因此,您需要将画布的宽度和高度设置为video.videoWidthvideo.videoHeight属性,以获取网络摄像头video.videoHeight的完整质量的图像,或者调用ctx.drawImage(video, 0,0, 400, 300)以便在CSS缩放时在画布上重新缩放它,或者在getUserMedia调用期间直接设置必需项(最新规范是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> 

jsfiddle link for chrome and its https policy... chrome的jsfiddle链接及其https策略...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM