HTML5 镜像网络摄像头 canvas
HTML5 Mirroring webcam canvas
我正在尝试使用网络摄像头供稿 -(横向格式),剪掉中间位(纵向格式)并将其呈现为 canvas 以便它以 1080px x 1920px 的比例填充屏幕纵向(为此,我将切出的位缩放为 3.8)。然后我需要翻转这个 canvas 以便镜像图像。我已经成功地切掉了中间位,并将其渲染到 canvas...我只是不知道如何翻转它。
编辑
感谢所有将我指向 context.scale(-1, 1) 的人 - 我的问题是,我已经在使用秤了...我认为我的问题与储蓄有关上下文,但我尝试的一切都失败了?
<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);
要水平翻转,您可以使用 context.scale(-1, 1);
。
来自http://www.html5canvastutorials.com/advanced/html5-canvas-mirror-transform-tutorial/
编辑
万不得已,可以使用 CSS
#canvas {
-moz-transform: scaleX(-1);
-o-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
filter: FlipH;
-ms-filter: "FlipH";
}
如果需要,这都可以通过 javascript 动态应用。未经测试但应该可以正常工作!
您不应该使用 ctx.scale
和 ctx.translate
方法进行裁剪。
而是在加载视频时计算裁剪位置,然后在绘图循环的调用中应用这些计算出的位置。
完成后,很容易应用@Mahout 提议的context.scale(-1, 1);
。
请注意,在应用 scale()
.
之前,您还需要 context.translate(canvas.width, 0);
我重构了你的代码,因为你请求视频强制性的方式是 (chrome)。
我也更改了您的循环,以便仅在视频加载时调用它,无需尝试绘制任何尚不存在的内容,并且我将您的 setTimeout
更改为 requestAnimationFrame
方法,大约以 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.srcObject = 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>
我正在尝试使用网络摄像头供稿 -(横向格式),剪掉中间位(纵向格式)并将其呈现为 canvas 以便它以 1080px x 1920px 的比例填充屏幕纵向(为此,我将切出的位缩放为 3.8)。然后我需要翻转这个 canvas 以便镜像图像。我已经成功地切掉了中间位,并将其渲染到 canvas...我只是不知道如何翻转它。
编辑
感谢所有将我指向 context.scale(-1, 1) 的人 - 我的问题是,我已经在使用秤了...我认为我的问题与储蓄有关上下文,但我尝试的一切都失败了?
<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);
要水平翻转,您可以使用 context.scale(-1, 1);
。
来自http://www.html5canvastutorials.com/advanced/html5-canvas-mirror-transform-tutorial/
编辑
万不得已,可以使用 CSS
#canvas {
-moz-transform: scaleX(-1);
-o-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
filter: FlipH;
-ms-filter: "FlipH";
}
如果需要,这都可以通过 javascript 动态应用。未经测试但应该可以正常工作!
您不应该使用 ctx.scale
和 ctx.translate
方法进行裁剪。
而是在加载视频时计算裁剪位置,然后在绘图循环的调用中应用这些计算出的位置。
完成后,很容易应用@Mahout 提议的context.scale(-1, 1);
。
请注意,在应用 scale()
.
context.translate(canvas.width, 0);
我重构了你的代码,因为你请求视频强制性的方式是
我也更改了您的循环,以便仅在视频加载时调用它,无需尝试绘制任何尚不存在的内容,并且我将您的 setTimeout
更改为 requestAnimationFrame
方法,大约以 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.srcObject = 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>