需求:安卓原生app端接入腾讯人脸核身sdk,采集人脸信息和账号绑定。用户使用同一账号登录微信公众号h5端,h5采集人脸信息,调用腾讯人脸比对接口,和原生app端采集的人脸信息比对,是否是同一个人,然后再进行下一步操作。 H5实现思路:1.如何调用移动端设备摄像头 2.使用tracking.js捕捉人脸 3.对人脸进行拍照,描绘到canvas画布上面 4.将照片转换成base64格式 5.调用后台接口,后台调用腾讯人脸比对接口进行比对。(由于调用腾讯人脸比对接口需要签名,签名在后台做比较合适) 代码以及注释1.下载tracking.js 网址:https://trackingjs.com 将需要的js文件复制到静态资源文件夹 ![]() 2.使用video标签调用手机摄像头,playsinline、webkit-playsinline属性非常重要,如果不写会掉不起来苹果手机的摄像头。微信开发者文档上面有明确的说明,喜欢钻研的同学可以到微信开发者文档中查看文档。video和canvas的宽高的写法是为了适配手机屏幕的大小。 代码 ``` success(stream) { this.streamIns = stream; const video = document.getElementById("video"); // webkit内核浏览器 this.URL = window.URL || window.webkitURL; if ("srcObject" in video) { video.srcObject = stream; } else { video.src = this.URL.createObjectURL(stream); } // 苹果手机的系统弹框会阻止js的线程的继续执行 手动0.1秒之后自动执行代码 setTimeout(() => { video.play(); this.initTracker();// 人脸捕捉 }, 100); }, error(e) { this.scanTip = "访问用户媒体失败"; }, ``` 5.设置各种参数 实例化人脸捕捉实例对象 ``` // 人脸捕捉 设置各种参数 实例化人脸捕捉实例对象,注意canvas上面的动画效果。 initTracker() { this.context = document.getElementById("refCanvas").getContext("2d"); // 画布 this.canvas = document.getElementById("refCanvas"); this.tracker = new window.tracking.ObjectTracker("face"); // tracker实例 this.tracker.setInitialScale(4); this.tracker.setStepSize(2); // 设置步长 this.tracker.setEdgesDensity(0.1); try { this.trackertask = window.tracking.track("#video", this.tracker); // 开始追踪 } catch (e) { this.scanTip = "访问用户媒体失败,请重试"; } //开始捕捉方法 一直不停的检测人脸直到检测到人脸 this.tracker.on("track", (e) => { //画布描绘之前清空画布 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); if (e.data.length === 0) { this.scanTip = "未检测到人脸"; } else { e.data.forEach((rect) => { //设置canvas 方框的颜色大小 this.context.strokeStyle = "#42e365"; this.context.lineWidth = 2; this.context.strokeRect(rect.x, rect.y, rect.width, rect.height); }); if (!this.tipFlag) { this.scanTip = "检测成功,正在拍照,请保持不动2秒"; } // 1.5秒后拍照,仅拍一次 给用户一个准备时间 // falg 限制一直捕捉人脸,只要拍照之后就停止检测 if (!this.flag) { this.scanTip = "拍照中..."; this.flag = true; this.removePhotoID = setTimeout(() => { this.tackPhoto(); document.getElementById("video").pause(); this.tipFlag = true; }, 1500); } } }); }, ``` 6.拍照 绘制照片,计算照片大小,腾讯人脸比对接口对照片大小和格式有要求。 ``` // 拍照 tackPhoto() { // 在画布上面绘制拍到的照片 this.context.drawImage( document.getElementById("video"), 0, 0, this.vwidth, this.vwidth ); // 保存为base64格式 this.imgUrl = this.saveAsPNG(document.getElementById("refCanvas")); /** 拿到base64格式图片之后就可以在this.compare方法中去调用后端接口比较了,也可以调用getBlobBydataURI方法转化成文件再去比较 * 我们项目里有一个设置个人头像的地方,先保存一下用户的图片,然后去拿这个图片的地址和当前拍照图片给后端接口去比较。 * */ // this.compare(imgUrl) //判断图片大小 this.imgSize(); this.faceToTengXun(); // 人脸比对 this.close(); }, imgSize() { if (this.imgUrl) { // 获取base64图片byte大小 const equalIndex = this.imgUrl.indexOf("="); // 获取=号下标 let size; if (equalIndex > 0) { const str = this.imgUrl.substring(0, equalIndex); // 去除=号 const strLength = str.length; const fileLength = strLength - (strLength / 8) * 2; // 真实的图片byte大小 size = Math.floor(fileLength / 1024); // 向下取整 console.log("size", size + "KB"); } else { const strLength = this.imgUrl.length; const fileLength = strLength - (strLength / 8) * 2; size = Math.floor(fileLength / 1024); // 向下取整 console.log("size", size + "KB"); } if (size > 1024) { // 图片超过1M 按比例压缩 this.imgUrl = document .getElementById("refCanvas") .toDataURL("image/png", 1024 / size); } } }, // Base64转文件 getBlobBydataURI(dataURI, type) { var binary = window.atob(dataURI.split(",")[1]); var array = []; for (var i = 0; i < binary.length; i++) { array.push(binary.charCodeAt(i)); } return new Blob([new Uint8Array(array)], { type: type, }); }, // compare(url) { // let blob = this.getBlobBydataURI(url, 'image/png') // let formData = new FormData() // formData.append("file", blob, "file_" + Date.parse(new Date()) + ".png") // // TODO 得到文件后进行人脸识别 // }, // 保存为png,base64格式图片 saveAsPNG(c) { return c.toDataURL("image/png", 0.4); }, ``` 7. 人脸采集之后,移除实例化对象,初始化参数和css样式部分代码 ``` close() { this.flag = false; this.tipFlag = false; this.showContainer = false; this.context = null; this.scanTip = "人脸识别中..."; clearTimeout(this.removePhotoID); if (this.streamIns) { this.streamIns.enabled = false; this.streamIns.getTracks()[0].stop(); this.streamIns.getVideoTracks()[0].stop(); } this.streamIns = null; this.trackertask.stop(); this.tracker = null; } .face-capture { display: flex; flex-direction: column; align-items: center; justify-content: center; } .tip { position: fixed; top: 48px; z-index: 5; font-size: 18px; font-family: PingFangSC-Medium, PingFang SC; font-weight: 500; color: #333333; line-height: 25px; } .face-capture video, .face-capture canvas { position: fixed; top: 117.5px; object-fit: cover; z-index: 2; background-repeat: no-repeat; background-size: 100% 100%; } .face-capture .img-cover { position: fixed; top: 63px; width: 375px; height: 375px; object-fit: cover; z-index: 3; background-repeat: no-repeat; background-size: 100% 100%; } .face-capture .contentp { position: fixed; top: 438px; font-size: 18px; font-weight: 500; color: #333333; } .face-capture .rect { border: 2px solid #0aeb08; position: fixed; z-index: 4; } .img-face { display: flex; flex-direction: column; align-items: center; justify-content: center; } .img-face .imgurl { position: fixed; top: 117.5px; width: 266px; height: 266px; border-radius: 133px; } ``` 1.人脸捕捉技术使用的tracking.js,关键是要理解它的运作原理和一下参数配置。 2.因为要调用手机媒体设备,兼容性问题是大问题,特别是苹果手机的问题,往往不知道如何下手,需要有丰富的开发经验和各种曲线救国的开发思想。 3.那个梦真的很重要。 4.对,美女更重要。 |