HTML5 Mirror Cloth Webcams

I'm trying to take a webcam channel - (landscape format), cut out the middle bit (portrait format) and render it on the canvas so that it fills the screen portrait 1080px to 1920px (for this I scale the bit I cut to 3.8). Then I need to flip this canvas so that the image is mirrored. I managed to cut out the middle bit and do it on the canvas ... I just can't figure out how to flip it.

Edit

Thanks to all the people who pointed me to context.scale (-1, 1) - my problem is that I am already using scale ... I think my problems are related to keeping the context, but all I try is not It worked?

<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); 
+4
source share
2 answers

You should not ctx.scale using the ctx.scale and ctx.translate .

Instead, when loading your video, calculate the cropping positions, and then apply these calculated positions in the call to the drawing cycle.

When this is done, it is easy to apply context.scale(-1, 1); as suggested by @Mahout.
Note that before applying scale() you will also need context.translate(canvas.width, 0); .

I reorganized your code because the way you requested the video masters is out of date (like chrome about it).

I changed your loop too, so that it only happens when a video is uploaded, you don’t have to try to draw everything that doesn’t exist yet, and I changed your setTimeout to requestAnimationFrame , which fires at about 30 frames per second.

 // 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); 
 body,html{margin:0} canvas{ border:1px solid;} 
 <canvas id="canvas" height="1920" width="1080"></canvas> 

jsfiddle for chrome

+4
source

To move horizontally you can use context.scale(-1, 1); .

From http://www.html5canvastutorials.com/advanced/html5-canvas-mirror-transform-tutorial/

EDIT

As a last resort, this CSS can be used

 #canvas { -moz-transform: scaleX(-1); -o-transform: scaleX(-1); -webkit-transform: scaleX(-1); transform: scaleX(-1); filter: FlipH; -ms-filter: "FlipH"; } 

If necessary, all this can be applied dynamically using javascript. Unverified, but hopefully works!

0
source

All Articles