简体   繁体   中英

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 .

Problem

I'm not succeeding in getting the whole video area from the Video element to the Canvas with Context2D's drawImage . Althought the Video is 400 by 300

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

and the canvas is the same 400 by 300

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

and when I draw I specify for both source and target 400 by 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 .

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.

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.

Canvas2dContext.drawImage(video, x, y) will take the frame size, (which can be set by the mandatory of 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 ;-)

 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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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