需求
混合App开发,原生壳子+webApp,在web部分调用原生摄像头功能并且在网页指定区域显示摄像头内容,同时可以手动拍照并进行人脸识别,将识别结果显示在网页上。
技术栈
vue、Html5、video标签、Android、IOS、百度AI
分析
1、使用navigator.mediaDevices.getUserMedia调用系统原生摄像头功能
2、video标签显示摄像头内容
3、canvas标签获取图片
4、将图像上传服务器,通过百度AI识别图片
5、web显示识别结果
核心代码
1、调用系统原生摄像头功能并使用video标签显示
html:<videoid="webcam":style="videoStyle":width="videoWidth":height="videoHeight"looppreload></video>
JavaScript:initVideo() {let that = this;this.video = document.getElementById("webcam");setTimeout(() => {if (navigator.mediaDevices.getUserMedia ||navigator.getUserMedia ||navigator.webkitGetUserMedia ||navigator.mozGetUserMedia) {//调用用户媒体设备, 访问摄像头this.getUserMedia({video: {width: {ideal: that.videoWidth,max: that.videoWidth},height: {ideal: that.videoHeight,max: that.videoHeight},facingMode: "user", //前置摄像头frameRate: {ideal: 30,min: 10}}},this.videoSuccess,this.videoError);} else {this.$toast.center("摄像头打开失败,请检查权限设置!");}}, 300);},getUserMedia(constraints, success, error) {if (navigator.mediaDevices.getUserMedia) {//最新的标准APInavigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);} else if (navigator.webkitGetUserMedia) {//webkit核心浏览器navigator.webkitGetUserMedia(constraints, success, error);} else if (navigator.mozGetUserMedia) {//firfox浏览器navigator.mozGetUserMedia(constraints, success, error);} else if (navigator.getUserMedia) {//旧版APInavigator.getUserMedia(constraints, success, error);}},videoSuccess(stream) {this.mediaStreamTrack = stream;this.video.srcObject = stream;this.video.play();},videoError(error) {console.error(error);this.$toast.center("摄像头打开失败,请检查权限设置!");},
2、canvas获取摄像头图片
JavaScript:this.canvas = document.createElement("canvas");....let context = this.canvas.getContext("2d");context.drawImage(this.video, 0, 0, this.videoWidth, this.videoHeight);this.imgSrc = this.canvas.toDataURL("image/png");
3、调用百度AI识别图片
JavaScript:let that = this;let base64Data = this.canvas.toDataURL();let blob = this.dataURItoBlob(base64Data); //var file = new FormData();file.append("file", blob);file.append("key", that.uuid);util.ajax.post("XXXXXXXXXX", file, {headers: {"Content-Type": "multipart/form-data"}}).then(function(response) {if ((response.status = 200)) {.....识别成功,显示结果} else {......识别失败}}).catch(function(error) {console.error(error);});//base64转换为BlobdataURItoBlob(base64Data) {var byteString;if (base64Data.split(",")[0].indexOf("base64") >= 0)byteString = atob(base64Data.split(",")[1]);else byteString = unescape(base64Data.split(",")[1]);var mimeString = base64Data.split(",")[0].split(":")[1].split(";")[0];var ia = new Uint8Array(byteString.length);for (var i = 0; i < byteString.length; i++) {ia[i] = byteString.charCodeAt(i);}return new Blob([ia], { type: mimeString });},
手机适配
1、由于Android6之后,Android的权限管理出现变化,Android原生的壳子,需要做如下处理:
myWebView.setWebChromeClient(new WebChromeClient() {@TargetApi(Build.VERSION_CODES.LOLLIPOP)@Overridepublic void onPermissionRequest(final PermissionRequest request) {request.grant(request.getResources());}});
2、IOS系统,Safari11之后可用
3、OverconstrainedError错误,部分Android手机会报OverconstrainedError错误,原因是摄像头参数设置不合理,找不到指定设置。
我的视频课
下面是我录制的一些视频课,欢迎大家围观~
《Android HyBrid App开发实战》
本课程为Android HyBrid App开发实战课程,由浅入深,从三种App的历史和特点开始,介绍了Android WebView的使用、Java和JS交互的原生方式、著名的WebView安全漏洞、JSBridge的原理和使用,最后通过一个网上商城的实战综合全部内容,让同学们掌握并深入理解Android HyBrid App开发。
《彻底搞定JVM》
JVM是Java中重要的也是较难理解的内容;
面试者对JVM的了解程度某种程度上反映了面试者技术深度,所以JVM也是面试时经常考察的内容;
本课程从JVM运行流程、数据运行时区域组成部分、类加载机制、垃圾回收机制、内存模型、常见面试题讲解等角度出发,帮你彻底搞定JVM,拿下心仪Offer;
《Android性能优化参考》
本课程包含了Android中的App启动优化、UI优化、内存优化、图片优化、耗电量等常见的性能优化场景,通过学习此课程,你将对整个Android性能优化体系有清晰的认识。
性能优化作为Android高级开发的必备技能,也是大厂面试必考的题目,是体现一个人技术深度最好的试金石。
《面试之排序算法》
排序算法是我们面试被问到最多的基础算法,本课程详细介绍了七种排序算法,包括插入排序、选择排序、冒泡排序、谢尔排序、快速排序、堆积排序和二路并归排序。每种算法都详细介绍了核心思想、详细步骤、时间复杂度和代码实现,希望帮助大家深入理解排序算法,搞定面试!
《AI导论》
介绍人工智能AI的诞生历史和到现在为止的不同发展阶段;介绍了AI领域中常见的名词概念和其关系,包括机器学习、深度学习、神经网络结构搜索 NAS、生成对抗网络 GAN等;最后对AI发展做出展望。
本课程属于导论课程,旨在帮助同学们从宏观层面把握AI,建立AI的知识体系。
《Java注解精讲》
本课程详细介绍了Java中的注解机制,包括注解的定义和分类,注解的使用和自定义,注解的源码和架构分析;
本课程语言简单凝练,视频短小精悍,让你一次彻底搞懂Java注解!
《Java反射精讲》
反射是Java中重要的也是较难理解的内容;
本课程从反射的定义、作用、原理和使用出发,全方位帮你彻底搞定反射;
好家伙,随手就是一个赞~
给作者买瓶咖啡提提神~