| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- <template>
- <!-- 人脸识别页面 -->
- <view class="content">
- <!-- 拍照区域 -->
- <view class="cameraField">
- <!-- 上传的人脸图片 -->
- <canvas
- canvas-id="canvas"
- id="canvas"
- type="2d"
- style="width: 100%; height: 100%"
- ></canvas>
- <!-- 提示框 -->
- <view class="hint" v-if="isShow3">
- <image :src="hintImage" />
- {{ hintWord }}
- </view>
- <!-- 头像限制框 -->
- <image
- class="head"
- src="../../static/images/head1.png"
- mode="scaleToFill"
- />
- </view>
- <!-- 控件区域 -->
- <view class="controlField">
- <!-- 拍照控件 -->
- <view class="control1" v-if="isShow1">
- <view class="light">
- <!-- <image class="light" src="../../static/images/light.png" /> -->
- </view>
- <view @click="takePhoto()">
- <image class="take" src="../../static/images/take.png" />
- </view>
- <view class="change">
- <!-- <image class="change" src="../../static/images/change.png" /> -->
- </view>
- </view>
- <!-- 重拍/上传控件 -->
- <view class="control2" v-if="isShow2">
- <view @click="resetPhoto">重拍</view>
- <view @click="upload">使用照片</view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { EXIF } from "../../node_modules/exif-js/exif"; //引入exif.js判断图片旋转方向
- import { mapState, mapMutations } from "vuex"; //引入vuex
- import {
- pathToBase64,
- base64ToPath,
- } from "../../js_sdk/mmmm-image-tools/index.js";
- export default {
- data() {
- return {
- isShow1: true, //拍照控件
- isShow2: false, //重拍/上传控件
- isShow3: true, //提示框
- // isShow4: false, //“上传中”提示框
- hintImage: "../../static/images/hint@2x.png", //提示图标
- hintWord: "请勿遮挡面部", //提示文字
- imgPath: "", //上传的人脸图片本地路径
- tipFlag: "", //手机机型
- maxWidth: "", //手机屏幕宽度
- maxHeight: "", //手机屏幕高度
- };
- },
- computed: mapState(["position", "userData"]), //vuex.state
- onLoad(options) {
- //判断设备机型
- let that = this;
- (function () {
- var u = navigator.userAgent;
- var isAndroid = u.indexOf("Android") > -1 || u.indexOf("Linux") > -1; //android终端或者uc浏览器
- var isiOS = u.indexOf("iPhone") > -1; //苹果手机
- if (isiOS) {
- that.tipFlag = "ios";
- }
- if (isAndroid) {
- that.tipFlag = "Android";
- }
- })();
- },
- methods: {
- ...mapMutations(["getPosition", "getUserData"]), //vuex.mutations
- //拍照控件变重拍上传控件
- takeToReset() {
- this.isShow1 = !this.isShow1;
- this.isShow2 = !this.isShow2;
- },
- //拍照
- takePhoto() {
- this.photo();
- },
- //重拍
- resetPhoto() {
- this.isShow1 = !this.isShow1;
- this.isShow2 = !this.isShow2;
- this.photo();
- },
- //照片
- photo() {
- let that = this;
- uni.chooseImage({
- count: 1,
- sourceType: ["camera"],
- sizeType: ["compressed"],
- success: (res) => {
- //压缩所选图片
- // let path = res.tempFilePaths[0]; //压缩图路径
- // let targetWidth = 150;
- // let targetHeight = 200;
- // let ctx = uni.createCanvasContext("canvas");
- // ctx.drawImage(path, 0, 0, 300, 400); //x设置成1000是因为不让压缩图出现在屏幕
- // ctx.draw(false, () => {
- // // canvas导出为图片路径
- // uni.canvasToTempFilePath({
- // canvasId: "canvas",
- // fileType: "jpg", //支持jpg或png
- // quality: 0.92, //图片质量
- // success(res3) {
- // let path1 = res3.tempFilePath;
- // that.toBase64(path1); //转base64图片
- // },
- // });
- // }),
- //绘制图片到页面
- that.imgPath = res.tempFilePaths[0]; //这就是要的blod
- //获取设备屏幕尺寸
- uni.getSystemInfo({
- success: function (res2) {
- that.maxWidth = res2.windowWidth;
- let base = 4 / 3;
- that.maxHeight = that.maxWidth * base;
- //判断设备机型
- if (that.tipFlag == "ios") {
- let canvas = uni.createCanvasContext("canvas");
- canvas.drawImage(
- that.imgPath,
- 0,
- 0,
- that.maxWidth,
- that.maxHeight
- ); //苹果机图片显示
- canvas.draw();
- uni.canvasToTempFilePath({
- width: that.maxWidth,
- height: that.maxHeight,
- destWidth: that.maxWidth,
- destHeight: that.maxHeight,
- canvasId: "canvas",
- fileType: "jpg", //支持jpg或png
- quality: 1, //图片质量
- success(res3) {
- let path1 = res3.tempFilePath;
- console.log(path1);
- that.$store.state.imageBase = path1;
- // that.toBase64(path1); //转base64图片
- },
- });
- that.takeToReset(); //图片显示后显示重拍控件
- } else {
- that.detail(that.imgPath); //安卓机图片绘制
- }
- },
- });
- },
- });
- },
- //安卓机图片修正
- async detail(url) {
- let Orientation = 1;
- //获取图片META信息
- await this.getImageTag(url, "Orientation", function (e) {
- if (e != undefined) Orientation = e;
- });
- var img = null;
- var canvas = null;
- await this.comprossImage(url, function (e) {
- img = e.img;
- canvas = e.canvas;
- });
- // console.log(Orientation,"Orientation")
- //如果方向角不为1,都需要进行旋转
- switch (Orientation) {
- case 6: //需要顺时针(向右)90度旋转
- this.rotateImg(img, "right", canvas);
- break;
- case 8: //需要逆时针(向左)90度旋转
- this.rotateImg(img, "left", canvas);
- break;
- case 3: //需要180度旋转 转两次
- this.rotateImg(img, "right", canvas, 2);
- break;
- default:
- this.rotateImg(img, "", canvas);
- break;
- }
- },
- async comprossImage(imgSrc, func) {
- if (!imgSrc) return 0;
- return new Promise((resolve, reject) => {
- uni.getImageInfo({
- src: imgSrc,
- success(res) {
- let img = new Image();
- img.src = res.path;
- // console.log(img);
- let canvas = uni.createCanvasContext("canvas");
- let obj = new Object();
- obj.img = img;
- obj.canvas = canvas;
- resolve(func(obj));
- },
- });
- });
- },
- getImageTag(file, tag, suc) {
- if (!file) return 0;
- return new Promise((resolve, reject) => {
- /* eslint-disable func-names */
- // 箭头函数会修改this,所以这里不能用箭头函数
- let imgObj = new Image();
- imgObj.src = file;
- // console.log(imgObj);
- uni.getImageInfo({
- src: file,
- success(res) {
- EXIF.getData(imgObj, function () {
- EXIF.getAllTags(this);
- let or = EXIF.getTag(this, "Orientation"); //这个Orientation 就是我们判断需不需要旋转的值了,有1、3、6、8
- resolve(suc(or));
- });
- },
- });
- });
- },
- rotateImg(img, direction, canvas, times = 1) {
- // console.log("开始旋转");
- //最小与最大旋转方向,图片旋转4次后回到原方向
- var min_step = 0;
- var max_step = 3;
- if (img == null) return;
- //img的高度和宽度不能在img元素隐藏后获取,否则会出错
- var height = img.height;
- var width = img.width;
- let maxWidth = this.maxWidth;
- let maxHeight = this.maxHeight;
- var step = 0;
- if (step == null) {
- step = min_step;
- }
- if (direction == "right") {
- step += times;
- //旋转到原位置,即超过最大值
- step > max_step && (step = min_step);
- } else if (direction == "left") {
- step -= times;
- step < min_step && (step = max_step);
- } else {
- //不旋转
- step = 0;
- }
- //旋转角度以弧度值为参数
- var degree = (step * 90 * Math.PI) / 180;
- var ctx = uni.createCanvasContext("canvas");
- // console.log(degree);
- // console.log(step);
- switch (step) {
- case 1:
- // console.log("右旋转 90度");
- width = maxHeight;
- height = maxWidth;
- ctx.rotate(degree);
- ctx.drawImage(img.src, 0, -height, width, height);
- ctx.draw();
- uni.canvasToTempFilePath({
- width: maxHeight,
- height: maxWidth,
- destWidth: maxHeight,
- destHeight: maxWidth,
- canvasId: "canvas",
- fileType: "jpg", //支持jpg或png
- quality: 1, //图片质量
- success(res3) {
- let path1 = res3.tempFilePath;
- console.log(path1);
- this.$store.state.imageBase = path1;
- // that.toBase64(path1); //转base64图片
- },
- });
- this.takeToReset();
- break;
- case 2:
- //console.log('旋转 180度')
- width = maxWidth;
- height = maxHeight;
- ctx.rotate(degree);
- ctx.drawImage(img.src, -width, -height, width, height);
- ctx.draw();
- uni.canvasToTempFilePath({
- width: maxWidth,
- height: maxHeight,
- destWidth: maxWidth,
- destHeight: maxHeight,
- canvasId: "canvas",
- fileType: "jpg", //支持jpg或png
- quality: 1, //图片质量
- success(res3) {
- let path1 = res3.tempFilePath;
- console.log(path1);
- this.$store.state.imageBase = path1;
- // that.toBase64(path1); //转base64图片
- },
- });
- this.takeToReset();
- break;
- case 3:
- // console.log("左旋转 90度");
- width = maxHeight;
- height = maxWidth;
- ctx.rotate(degree);
- ctx.drawImage(img.src, -width, 0, width, height);
- ctx.draw();
- uni.canvasToTempFilePath({
- width: maxHeight,
- height: maxWidth,
- destWidth: maxHeight,
- destHeight: maxWidth,
- canvasId: "canvas",
- fileType: "jpg", //支持jpg或png
- quality: 1, //图片质量
- success(res3) {
- let path1 = res3.tempFilePath;
- console.log(path1);
- this.$store.state.imageBase = path1;
- // that.toBase64(path1); //转base64图片
- },
- });
- this.takeToReset();
- break;
- default:
- //不旋转
- width = maxWidth;
- height = maxHeight;
- ctx.drawImage(img.src, 0, 0, width, height);
- ctx.draw();
- uni.canvasToTempFilePath({
- width: maxWidth,
- height: maxHeight,
- destWidth: maxWidth,
- destHeight: maxHeight,
- canvasId: "canvas",
- fileType: "jpg", //支持jpg或png
- quality: 1, //图片质量
- success(res3) {
- let path1 = res3.tempFilePath;
- console.log(path1);
- this.$store.state.imageBase = path1;
- // that.toBase64(path1); //转base64图片
- },
- });
- this.takeToReset();
- break;
- }
- },
- //上传图片
- upload() {
- let idnum = this.$store.state.idnum;
- let image = this.$store.state.imageBase;
- this.isShow3 = !this.isShow3; //关闭提示框
- uni.showToast({
- title: "人脸匹配中",
- icon: "loading",
- mask: true,
- duration: 2000,
- });
- if (idnum && image) {
- uni.request({
- url: "https://jtishfw.ncjti.edu.cn/yinxin/ncjtSecurityManagement/verifyBase64ImagesWithIDNumber",
- data: {
- idnum: idnum,
- image: image,
- },
- header: { "content-type": "application/x-www-form-urlencoded" },
- method: "POST",
- sslVerify: true,
- success: ({ data, statusCode, header }) => {
- if (data.error) {
- uni.showToast({
- title: "人脸匹配失败",
- icon: "error",
- mask: true,
- duration: 1000,
- });
- setTimeout(this.back, 1000);
- } else {
- this.$store.state.sex = data.sex;
- this.$store.state.examNumber = data.examNumber;
- setTimeout(this.uploadSucceed, 500);
- }
- },
- fail: () => {
- uni.showToast({
- title: "人脸提交失败",
- icon: "error",
- mask: true,
- duration: 1000,
- });
- setTimeout(this.back, 1000);
- },
- });
- } else {
- uni.showToast({
- title: "image或idnum不能为空",
- icon: "error",
- mask: true,
- duration: 1500,
- });
- this.isShow3 = !this.isShow3; //显示提示框
- }
- },
- //人脸采集成功
- uploadSucceed() {
- this.hintWord = "人脸匹配成功";
- this.hintImage = "../../static/images/success@2x.png";
- this.isShow3 = !this.isShow3;
- this.takeToReset();
- setTimeout(this.navigateToConfirm, 1500);
- },
- //图片转Base64
- toBase64(path) {
- pathToBase64(path)
- .then((base64) => {
- this.$store.state.imageBase = base64;
- console.log(this.$store.state.imageBase);
- })
- .catch((error) => {
- console.error(error);
- });
- },
- //跳转人脸采集确认页面
- navigateToConfirm() {
- uni.navigateTo({
- url: "/pages/confirm/confirm",
- });
- },
- //返回重新拍照
- back() {
- uni.reLaunch({
- url: "/pages/faceSearch/faceSea",
- });
- },
- },
- };
- </script>
- <style lang="scss">
- @import url("./css/faceSea.min.css");
- </style>
|