web网页调用电脑摄像头拍取照片

看不见看不见看不见 2024-07-16 09:03:02 阅读 88

之前用的是element-ui的上传图片组件,但是突然变更需求,要求相机拍摄,不让上传文件夹图片,并且上传至服务器

我们分为四步

第一步检查当前设备是否有摄像设备

window 身上自带了一个 navigator 属性,这个对象有一个叫做 mediaDevices 的属性是我们即将用到的。

<code>let navigator = window.navigator.mediaDevices;

let devices = await navigator.enumerateDevices();

console.log(navigator)

我们先看一下这个对象有哪些方法,你也许会看到下面的场景,会发现这个属性身上只有一个值为 null 的 ondevicechange 属性,不要怕,真正要用的方法其实在它的原型身上。

在这里插入图片描述

让我们点开它的原型属性,注意下面这两个方法,这是我们本章节的主角。

在这里插入图片描述

我们到这一步只是需要判断当前设备是否有摄像头,我们先调取 enumerateDevices 函数来查看当前媒体设备是否存在。它的返回值是一个 promise 类型,我们直接用 async 和 await 来简化一下代码。

<code> let navigator = window.navigator.mediaDevices;

let devices = await navigator.enumerateDevices();

console.log(devices);

在这里插入图片描述

从上图可以看出,我的电脑有两个音频设备和一个视频设备,那么我们就可以放下进行下一步了。

第二部获取摄像头

<code>//html部分

<video id="video" style="width: 600px" class="mb10"></video>code>

//js部分

navigator

.getUserMedia({

video: {

width: 500,

height: 500,

},

})

.then((mediaStream) => {

this.video = document.querySelector("video");

this.video.srcObject = mediaStream;

this.video.onloadedmetadata = function (e) {

video.play();

};

})

.catch((err) => {

console.log(err);

});

运行之后会显示

在这里插入图片描述

第三步点击拍摄按钮进行截取照片

<code>//拍摄按钮事件

clic() {

const canvas = document.createElement("canvas");

canvas.width = 200;

canvas.height = 200;

let ctx = canvas.getContext("2d");

ctx.drawImage(this.video, 0, 0, canvas.width, canvas.height);

let image = new Image();

let myImage = canvas.toDataURL("image/png");

image.src = canvas.toDataURL("image/png");

this.dataURLtoFile(myImage, "signature.png");

this.videoVisible = false; //相机展示画面是弹窗,这里是关闭弹窗

return image;

},

第四步将截取的图片转为base64字符串上传

dataURLtoFile(dataurl, filename) {

//将base64转换为文件,dataurl为base64字符串,filename为文件名(必须带后缀名,如.jpg,.png)

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);

}

let fileList = new File([u8arr], filename, { type: mime });

this.update(fileList); //图片上传

return new File([u8arr], filename, { type: mime });

},

//上传

update(file) {

let param = new FormData(); //创建form对象

param.append("file", file, file.name); //通过append向form对象添加数据

let url = process.env.VUE_APP_BASE_API + "/file/upload";

let headers = {

Authorization: "Bearer " + getToken(),

};

axios

.post(url, param, { headers: headers })

.then((response) => {

//这里是接口返回的数据用于展示

this.lvimage.push(response.data.data.url);

}

})

.catch((e) => {});

},

完整代码

html部分

//这里是上传图片以及图片展示标签

<div>

<el-image

class="upload_add"code>

v-for="url in lvimage"code>

:key="url"code>

:src="url"code>

>

</el-image>

<img

v-if="lvimage.length < 3"code>

src="../../../image/upload_add.png"code>

class="upload_add"code>

@click="uploadsuccess(1)"code>

/>

</div>

//弹窗里面显示拍摄的内容

<el-dialog :visible.sync="videoVisible">code>

<div class="flex flex-d a-center">code>

<video id="video" style="width: 600px" class="mb10"></video>code>

<el-button @click="clic" type="primary">拍摄</el-button>code>

</div>

</el-dialog>

JS部分

import axios from "axios";

//data里面定义的数据

videoVisible: false,

video: "",

lvimage: [],

//methods里面的方法

//点击上传按钮的事件

async uploadsuccess() {

this.videoVisible = true;

let navigator = window.navigator.mediaDevices;

let devices = await navigator.enumerateDevices();

console.log(devices);

navigator

.getUserMedia({

video: {

width: 500,

height: 500,

},

})

.then((mediaStream) => {

this.video = document.querySelector("video");

this.video.srcObject = mediaStream;

this.video.onloadedmetadata = function (e) {

video.play();

};

})

.catch((err) => {

console.log(err);

});

},

//点击拍摄按钮的事件

clic() {

const canvas = document.createElement("canvas");

canvas.width = 200;

canvas.height = 200;

let ctx = canvas.getContext("2d");

ctx.drawImage(this.video, 0, 0, canvas.width, canvas.height);

let image = new Image();

let myImage = canvas.toDataURL("image/png");

image.src = canvas.toDataURL("image/png");

this.dataURLtoFile(myImage, "signature.png");

this.videoVisible = false;

return image;

},

//将图片转为base64

dataURLtoFile(dataurl, filename) {

//将base64转换为文件,dataurl为base64字符串,filename为文件名(必须带后缀名,如.jpg,.png)

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);

}

let fileList = new File([u8arr], filename, { type: mime });

this.update(fileList); //图片上传

return new File([u8arr], filename, { type: mime });

},

//上传服务器

update(file) {

let param = new FormData(); //创建form对象

param.append("file", file, file.name); //通过append向form对象添加数据

let url = process.env.VUE_APP_BASE_API + "/file/upload";

let headers = {

Authorization: "Bearer " + getToken(),

};

axios

.post(url, param, { headers: headers })

.then((response) => {

if (response.data.code == 200) {

if (this.uplodebtn == 1) {

this.lvimage.push(response.data.data.url);

} else if (this.uplodebtn == 2) {

this.djimage.push(response.data.data.url);

} else {

this.zsimage.push(response.data.data.url);

}

}

})

.catch((e) => {});

},



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。