HTML5镜像网络摄像头画布

Rob*_*Rob 4 javascript webcam html5 canvas webcam-capture

我正在尝试拍摄网络摄像头 - (横向格式),剪切中间位(纵向格式)并将其渲染到画布,使其填充屏幕纵向1080px到1920px(为此我缩放我剪切的位出3.8).然后我需要翻转这个画布,以便镜像图像.我已经成功地删除了中间位,并将其呈现给画布......我只是想弄清楚如何翻转它.

编辑

感谢所有在context.scale(-1,1)指出我的人 - 我的问题是,我已经在使用scale ...我认为我的问题与保存上下文有关,但我尝试的一切没能奏效?

<script>
       // Put event listeners into place
        window.addEventListener("DOMContentLoaded", function() {
            // Grab elements, create settings, etc.
            var canvas = document.getElementById("canvas"),
                context = canvas.getContext("2d"),
                video = document.getElementById("video"),
                videoObj = { 
                    video: {
                        mandatory: {
                            minWidth: 1280,
                            minHeight: 720,
                            /*Added by Chad*/
                            maxWidth: 1280,
                            maxHeight: 720
                        }
                    }
                },
                errBack = function(error) {
                    console.log("Video capture error: ", error.code); 
                };

            // Put video listeners into place
            if(navigator.getUserMedia) { // Standard
                navigator.getUserMedia(videoObj, function(stream) {
                    video.src = stream;
                    video.play();
                }, errBack);
            } else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
                navigator.webkitGetUserMedia(videoObj, function(stream){
                    video.src = window.URL.createObjectURL(stream);
                    video.play();
                }, errBack);
            } else if(navigator.mozGetUserMedia) { // WebKit-prefixed
                navigator.mozGetUserMedia(videoObj, function(stream){
                    video.src = window.URL.createObjectURL(stream);
                    video.play();
                }, errBack);
            }

            /*
                video : video source tag
                320,0 : the shift coords
                320,180 : the canvas size
                0,0 : no shift in the canvas
                640,360 : important ! it’s the native resolution of video source
            */
            context.scale(3.8,3.8);

            function loop(){
               context.drawImage(video, 450, 0, 1080, 1920, 0, 0, 720, 1280);
               setTimeout(loop, 1000 / 30);
            }

            loop();


        }, false);
</script> 


    <video id="video" height="1080" width="1920" autoplay></video>
    <canvas id="canvas" height="1920" width="1080"></canvas>


// Put event listeners into place
window.addEventListener("DOMContentLoaded", function() {
    // Grab elements, create settings, etc.
    var canvas = document.getElementById("canvas"),
        context = canvas.getContext("2d"),
        video = document.getElementById("video"),
        videoObj = { 
            video: {
                mandatory: {
                    minWidth: 1280,
                    minHeight: 720,
                    /*Added by Chad*/
                    maxWidth: 1280,
                    maxHeight: 720
                }
            }
        },
        errBack = function(error) {
            console.log("Video capture error: ", error.code); 
        };

    // Put video listeners into place
    if(navigator.getUserMedia) { // Standard
        navigator.getUserMedia(videoObj, function(stream) {
            video.src = stream;
            video.play();
        }, errBack);
    } else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
        navigator.webkitGetUserMedia(videoObj, function(stream){
            video.src = window.URL.createObjectURL(stream);
            video.play();
        }, errBack);
    } else if(navigator.mozGetUserMedia) { // WebKit-prefixed
        navigator.mozGetUserMedia(videoObj, function(stream){
            video.src = window.URL.createObjectURL(stream);
            video.play();
        }, errBack);
    }

    /*
        video : video source tag
        320,0 : the shift coords
        320,180 : the canvas size
        0,0 : no shift in the canvas
        640,360 : important ! it’s the native resolution of video source
    */




    context.scale(-3.8,3.8);
    context.translate(-720,0);
    function loop(){
       context.drawImage(video, 450, 0, 1080, 1920, 0, 0, 720, 1280);
       setTimeout(loop, 1000 / 30);
    }

    loop();


}, false);
Run Code Online (Sandbox Code Playgroud)

Kai*_*ido 5

您不应该使用ctx.scalectx.translate方法进行裁剪.

相反,在加载视频时,计算裁剪位置,然后在绘图循环的调用中,应用这些计算的位置.

完成后,很容易应用context.scale(-1, 1);@Mahout提出的建议.
请注意,context.translate(canvas.width, 0);在应用之前您还需要scale().

我重构了你的代码,因为你请求视频强制执行的方式已经过时了(就像关于它的chrome一样).

我也改变了你的循环,为了只在视频加载时调用它,不需要尝试绘制任何不存在的东西,然后我setTimeoutrequestAnimationFrame方法改变了你的方法,它大约以30fps的速度发射.

// Put event listeners into place
window.addEventListener("DOMContentLoaded", function() {
	// Grab elements, create settings, etc.
	var canvas = document.getElementById("canvas"),
		context = canvas.getContext("2d"),
		// we don't need to append the video to the document
		video = document.createElement("video"),
		videoObj = 
		navigator.getUserMedia || navigator.mozGetUserMedia ? // our browser is up to date with specs ?
		{ 
		video: {
			width: { min: 1280,  max: 1280 },
			height: { min: 720,  max: 720 },
			require: ['width', 'height']
			}
		}:
		{
		video: {
			mandatory: {
				minWidth: 1280,
				minHeight: 720,
				maxWidth: 1280,
				maxHeight: 720
			}
		}
	},
	errBack = function(error) {
		console.log("Video capture error: ", error.code); 
	};
	// create a crop object that will be calculated on load of the video
	var crop;
	// create a variable that will enable us to stop the loop.
	var raf;
	
	navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
	// Put video listeners into place
		navigator.getUserMedia(videoObj, function(stream) {
			video.src = URL.createObjectURL(stream);
			video.onplaying = function(){
				var croppedWidth = ( Math.min(video.videoHeight, canvas.height) / Math.max(video.videoHeight,canvas.height)) * Math.min(video.videoWidth, canvas.width),
				croppedX = ( video.videoWidth - croppedWidth) / 2;
				crop = {w:croppedWidth, h:video.videoHeight, x:croppedX, y:0};
				// call our loop only when the video is playing
				raf = requestAnimationFrame(loop);
				};
			video.onpause = function(){
				// stop the loop
				cancelAnimationFrame(raf);
				}
			video.play();
		}, errBack);

	function loop(){
	   context.drawImage(video, crop.x, crop.y, crop.w, crop.h, 0, 0, canvas.width, canvas.height);
	   raf = requestAnimationFrame(loop);
	}
// now that our video is drawn correctly, we can do...
context.translate(canvas.width, 0);
context.scale(-1,1);

}, false);
Run Code Online (Sandbox Code Playgroud)
body,html{margin:0}
canvas{ border:1px solid;}
Run Code Online (Sandbox Code Playgroud)
<canvas id="canvas" height="1920" width="1080"></canvas>
Run Code Online (Sandbox Code Playgroud)

jsfiddle for chrome