https://blog.csdn.net/weixin_42120669/article/details/120044796?spm=1001.2014.3001.5501
引用 jszip 和 file-saver
npm install jszip --save
npm install file-saver --save
headImgSrc 点击打开摄像头
closeImgSrc 点击关闭摄像头
引用图片可以自行设置
<template>
<div>
<!--开启摄像头-->
<div class="imagbtn">
<img
@click="callCamera"
style="height: 100px; width: 100px"
:src="headImgSrc"
alt="摄像头"
/>
<img
@click="closeCamera"
style="height: 100px; width: 100px"
:src="closeImgSrc"
alt="关闭摄像头"
/>
<!--确认-->
<el-button
v-if="isnotbtn"
class="querybtn"
size="mini"
type="primary"
@click="photograph"
>拍照</el-button
>
<video
ref="video"
v-show="isnotbtn"
style="margin-left: 100px"
:width="imagwidth"
:height="imagheight"
autoplay
></video>
</div>
<div class="canvasimages" v-show="isnotcheckall">
<div class="canvas-images" v-show="isnotbtn">
<canvas
v-for="item in domains"
style="margin-left: 5px"
:ref="item"
:width="imagwidth"
:height="imagheight"
></canvas>
</div>
<el-button class="iconbtn" type="primary" @click="cicnspin"
>下载<i class="el-icon-upload el-icon--right icnspin"></i
></el-button>
</div>
</div>
</template>
<script>
import JSZip from "jszip";
import FileSaver from "file-saver";
export default {
data() {
return {
headImgSrc: require("../../../static/img/sxt.jpg"),
closeImgSrc: "../../../static/img/gbsxt.jpg",
isnotbtn: false,
isnotcanvas: false,
imagheight: 100,
imagwidth: 100,
domains: [],
arr: 0,
onecanvas: 0,
checkAll: false,
checkedCities: ["上海", "北京"],
isIndeterminate: true,
isnotcheckall: false,
icnspinimages: [],
arrcont: [],
};
},
methods: {
// 调用摄像头
callCamera() {
// H5调用电脑摄像头API
navigator.mediaDevices
.getUserMedia({
video: true,
})
.then((success) => {
this.isnotbtn = true;
// 摄像头开启成功
this.$refs["video"].srcObject = success;
// 实时拍照效果
this.$refs["video"].play();
})
.catch((error) => {
this.$message.error(
"摄像头开启失败,请检查摄像头是否可用!或者打开摄影头"
);
console.error("摄像头开启失败,请检查摄像头是否可用!");
});
},
// 拍照
photograph() {
this.isnotcheckall = true;
this.arr++;
this.onecanvas = this.onecanvas + this.arr;
this.domains.push(this.onecanvas);
let dataimage = this.domains[this.domains.length - 1];
this.$nextTick(() => {
this.$refs[dataimage][0]
.getContext("2d")
.drawImage(
this.$refs["video"],
0,
0,
this.imagheight,
this.imagwidth
);
this.icnspinimages.push(
this.$refs[dataimage][0].toDataURL("image/jpeg", 0.7)
);
});
},
// 关闭摄像头
closeCamera() {
if (!this.$refs["video"].srcObject) {
this.dialogCamera = false;
return;
}
let stream = this.$refs["video"].srcObject;
let tracks = stream.getTracks();
tracks.forEach((track) => {
track.stop();
});
this.$refs["video"].srcObject = null;
this.isnotbtn = false;
this.domains = [];
this.isnotcheckall = false;
this.arrcont = [];
},
handleCheckAllChange(val) {
this.checkedCities = val ? this.domains : [];
this.isIndeterminate = false;
},
handleCheckedCitiesChange(value) {
let checkedCount = value.length;
this.checkAll = checkedCount === this.domains.length;
this.isIndeterminate =
checkedCount > 0 && checkedCount < this.domains.length;
},
// 下载
cicnspin() {
this.dialogCamera = false;
var blogTitle = "图片压缩包"; //图片压缩包名称
var zip = new JSZip();
var imgs = zip.folder(blogTitle);
var baseList = []; //需要压缩图片的路径
var imgNameList = []; //单张图片名称
var arr = [];
let that = this;
for (let i = 0; i < this.icnspinimages.length; i++) {
imgNameList.push(i);
let code = "";
code =
"data:image/svg+xml;base64," +
window.btoa(unescape(encodeURIComponent(this.icnspinimages[i])));
arr.push(code);
let image = new Image();
image.src =
"data:image/svg+xml;base64," +
window.btoa(unescape(encodeURIComponent(this.icnspinimages[i]))); //给图片对象写入base64编码的svg流
var canvas = document.createElement("canvas"); //准备空画布
canvas.width = 200;
canvas.height = 200;
var context = canvas.getContext("2d"); //取得画布的2d绘图上下文
context.drawImage(image, 0, 0, 100, 100);
let url = this.icnspinimages[i]; // 得到图片的base64编码数据
canvas.toDataURL("image/png");
baseList.push(url.substring(22)); // 去掉ba
if (baseList.length === arr.length && baseList.length > 0) {
for (let k = 0; k < baseList.length; k++) {
imgs.file(k + ".png", baseList[k], {
//设置单张图片名称
base64: true,
});
}
zip
.generateAsync({
type: "blob",
})
.then(function (content) {
that.$nextTick(() => {
that.arrcont.push(content);
if (i == that.icnspinimages.length - 1) {
// 调用 FileSaver.js
FileSaver.saveAs(content, blogTitle + ".zip");
}
});
});
}
image.src = arr[i];
that.arrcont = [];
}
},
},
};
</script>
<style scoped>
.imagbtn {
display: flex;
align-content: center;
justify-content: start;
}
.querybtn {
/* width: 50px; */
height: 50px;
margin: auto 0;
border-radius: 15px;
/* font-size:30px; */
}
.images {
width: 640px;
height: 480px;
}
.canvasimages {
display: flex;
}
.iconbtn {
margin: auto 20px;
height: 50px;
}
.icnspin {
transform: rotate(180deg);
}
.canvas-images {
display: flex;
flex-wrap: wrap;
width: 100%;
}
</style>