【发布时间】:2021-01-24 01:24:51
【问题描述】:
我正在尝试让用户相机拍摄快照,然后将最终结果渲染到方形 fabricjs 画布上。
我使用浏览器的原生网络摄像头功能,因此它在我的笔记本电脑上以 640x480 分辨率显示。我向用户展示的方式是在设置为“object-fit:cover”的方形视图元素“camera-view”中显示视频提要以删除信箱(然后放大以匹配高度)。然后将图片放置在方形画布“用户照片”上,该画布也设置为“object-fit:cover”以包含矩形图像(隐藏侧面并匹配视频)。图像还需要在手机摄像头上正确显示纵向,这似乎可行。
我在尝试将这个“用户照片”复制到织物 js 画布时出现问题。我希望它只复制它所做的画布的正方形副本。然而,它总是来自偏心。我不想硬编码任何值,因为画布和视频框的大小可能会改变,或者视频的分辨率可能不同。我很确定在绘制新画布时我刚刚进行了一些计算,或者“object-fit:cover”约束可能导致了这种行为。
过去两天我一直在寻找和尝试如何正确地实现这一目标并且已经接近但它仍然不能完全按照它应该的方式工作。
我使用了这里的部分:fabric.js - create Image object from ImageData object of canvas API ,这里是 Crop Functionality using FabricJs,以及 Stack Overflow 周围的其他部分。
这是代码的主要部分,正在进行的全部工作在这里:JS Fiddle
const cameraView = document.querySelector("#camera-view");
const userPhoto = document.querySelector("#user-photo");
var canWidth = 400; //Will be calculate dynamically
var canHeight = 400;
var st = 'width:' + canWidth.toString() + 'px; height:' + canHeight.toString() + 'px';
cameraView.setAttribute("style", st);
userPhoto.setAttribute("style", st);
var canvas = new fabric.Canvas('photo-adjust', {
width: canWidth,
height: canHeight
});
function BuildFabricCanvas() {
const can = document.getElementById('user-photo');
var ctx = can.getContext('2d');
var landscape = can.width > can.height; //true if in landscape orientation
var leftTrim = landscape ? (can.width - can.height) : 0; //Not sure if works on portrait
var topTrim = landscape ? (can.height - canHeight)/2 : (can.height-can.width); //Not sure if works on portrait
var data = ctx.getImageData(leftTrim, topTrim, canWidth, canHeight); //Probably have these wrong
var c = document.createElement('canvas');
c.setAttribute('id', '_temp_canvas');
c.width = canWidth;
c.height = canHeight;
c.getContext('2d').putImageData(data, 0, 0);
fabric.Image.fromURL(c.toDataURL(), function(img) {
img.set({
'flipX': true,
});
img.left = 0;
img.top = 0;
canvas.add(img);
canvas.centerObject(img);
img.bringToFront();
c = null;
$('#_temp_canvas').remove();
canvas.renderAll();
});
}
function WebcamSetup() {
navigator.mediaDevices
.getUserMedia({
video: {
facingMode: "user"
},
audio: false
})
.then(function(stream) {
track = stream.getTracks()[0];
cameraView.srcObject = stream;
})
.catch(function(error) {
console.error("Oops. Something is broken.", error);
});
cameraView.classList.remove('d-none');
userPhoto.classList.add("d-none");
DisableButton('next');
document.getElementById('retake-photo').style.visibility = 'hidden';
document.getElementById('take-photo').style.visibility = 'visible';
}
WebcamSetup();
function TakeSnapshot() {
userPhoto.classList.remove("d-none");
userPhoto.width = cameraView.videoWidth;
userPhoto.height = cameraView.videoHeight;
userPhoto.getContext("2d").drawImage(cameraView, 0, 0);
cameraView.classList.add('d-none');
EnableButton('next');
TurnOffWebcam();
document.getElementById('take-photo').style.visibility = 'hidden';
document.getElementById('retake-photo').style.visibility = 'visible';
}
【问题讨论】:
标签: javascript canvas fabricjs crop webcam