1.打开摄像头
navigator.mediaDevices.getUserMedia获取摄像头,再把视频挂载到video上
<video ref="showVideo" :controls="false" :enable-progress-gesture="false" object-fit="cover"
:show-center-play-btn="false" class="video">
</video>
async getMedia() {
uni.showLoading({
title: '获取摄像头中...',
mask: true,
});
let videoStream = await navigator.mediaDevices.getUserMedia({
video: {
facingMode: "user", //前置摄像头
width: {
ideal: this.width //视频宽
},
height: {
ideal: this.height //视频高
}
},
audio: false,
})
this.video = document.getElementsByTagName('video')[0];
//挂在视频流
this.video.srcObject = videoStream;
//设置播放
//PS:手机端只有设置静音该方法调用才有效
this.video.play();
uni.hideLoading();
},
预览图
2.点击拍照
利用CanvasRenderingContext2D.drawImage获取图片的base64编码
const canvas = document.getElementsByTagName('canvas')[0];
// canvas.getContext(contextType)方法返回canvas 的上下文,如果上下文没有定义则返回 null。
// contextTypes属性"2d", 建立一个 CanvasRenderingContext2D 二维渲染上下文。
const context = canvas.getContext("2d");
// 设置宽高
canvas.width = this.width;
canvas.height = this.height;
// CanvasRenderingContext2D.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
// image————画布图像源;sx,sy画布图像源选择框的左上角 X 轴坐标;sWidth,sHeight 画布图像源 的矩形(裁剪)选择框的宽度与高度
// dx,dy————左上角在目标画布上 X Y轴坐标;dWidth,dHeight 在目标画布上绘制的宽度与高度
context.drawImage(this.video, 0, 0, this.width, this.height, 0 ,0, this.width, this.height);
const data = canvas.toDataURL("image/png");
在图像源中截取一部分放到画布的固定位置
3.上传文件流到后端
将base64转为文件流,用uni.uploadFile上传给后端
dataURLtoFile(dataurl, filename) {//将base64转换为文件
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type:mime});
},
let file = this.dataURLtoFile(data, 'photo.png');
uni.uploadFile({
url: 后端上传文件地址,
name: 'file',
file, //文件流
header: {
'Authorization': uni.getStorageSync('token')
},
formData: {
examPaperId: '',
},//可以添加表单内其他属性
success: (uploadFileRes) => {
},
fail: (err) => {
console.error('上传失败:', err);
}
});