javascript - HTML5 Aynalama web kamerası tuvali
Bir webcam akışını almaya çalışıyorum - (manzara formatı), ortasındaki kısmı kesip (portre formatı) bunu bir kanvasa render ederek ekranı portre 1080px x 1920px olacak şekilde doldurmak istiyorum (bunun için kestiğim kısmı 3,8 ile ölçeklendiriyorum). Sonra bu kanvası görüntü aynalanmış olacak şekilde çevirmem gerekiyor. Ortasındaki kısmı kesmeyi ve bunu kanvasa render etmeyi başardım... Sadece nasıl çevireceğimi bir türlü bulamıyorum.
Düzenle
context.scale(-1, 1) komutunu bana işaret eden herkese teşekkürler - sorunum şu ki, zaten scale kullanıyorum... Sanırım sorunlarım context'i kaydetmekle ilgili, ama denediğim her şey işe yaramadı.
<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);
Cevap #1
ctx.scale ve ctx.translate yöntemlerini kullanarak kırpma yapmamalısınız.
Bunun yerine, videonuz yüklendiğinde kırpma pozisyonlarını hesaplayın ve ardından çizim döngünüz çağrıldığında, bu hesaplanan pozisyonları uygulayın.
İşiniz bittiğinde, @Mahout tarafından önerildiği gibi context.scale(-1, 1); uygulamak kolaydır.
scale() uygulamadan önce ayrıca context.translate(canvas.width, 0); yapmanız gerektiğini unutmayın.
Kodunuzu yeniden düzenledim çünkü videonun zorunluluklarını isteme şekliniz güncel değil (Chrome hakkında da öyle).
Döngünü de değiştirdim, videonun yüklenmiş olduğunda çağırmak için, henüz var olmayan bir şeyi çizmeye çalışmana gerek yok, ve setTimeout kodunu requestAnimationFrame yöntemiyle değiştirdim, bu yöntem yaklaşık olarak 30fps hızında çalışır.
// 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>jsfiddle için Chrome
Cevap #2
Yatay olarak çevirmek için context.scale(-1, 1); kullanabilirsiniz.
Kaynak: http://www.html5canvastutorials.com/advanced/html5-canvas-mirror-transform-tutorial/
DÜZENLE
Son çare olarak, bu CSS kullanılabilir
#canvas {
-moz-transform: scaleX(-1);
-o-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
filter: FlipH;
-ms-filter: "FlipH";
}
Gerekirse, tüm bunlar javascript ile dinamik olarak uygulanabilir. Test edilmedi ama umarım çalışır!
