uniapp---app端人脸识别组件(宽屏版1280*800组件,需手动截屏拍人脸识别,踩坑,成长)

2023-11-26 21:30

本文主要是介绍uniapp---app端人脸识别组件(宽屏版1280*800组件,需手动截屏拍人脸识别,踩坑,成长),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、首先记录下踩到的坑

我这边做的是一个挂在门口的门牌机,可以用于扫脸签到,扫码签到,扫脸实现用的是live-pusher组件(代码很长,放在最下面,不能直接用,需要根据实际情况修改)去做的人脸识别,在测试安卓机上一切正常,在安卓宽屏设备(akuvox牌子的门禁机)上出现各种问题,最主要是不能用usb调试!!!只能打包调试太折磨了

坑1:官方live-pusher组件的snapshot方法没有触发回调,原因是该设备不会主动询问是否开启存储权限,需要手动设置如果遇到点击快门没反应,请检查是否主动开启了设备的存储权限,没有的话点击这里,按照这个地址(Dcloud社区)方法去操作

 给懒得跳链接的朋友放个传送门,主要就是下面附带的代码,用于申请设备权限

 图片中的代码:

    "permissionExternalStorage": {  "request": "always",  "prompt": "应用保存运行状态等信息,需要获取读写手机存储(系统提示为访问设备上的照片、媒体内容和文件)权限,请允许。"  }

坑2:获取设备的mac地址 这个真的是几经波折,最后在插件市场找到了救命稻草,mt-device-info - DCloud 插件市场

云插件官方使用指南:uni-app官网


除了踩坑,也有获取到在uniapp在特殊(宽屏)设备上开发app的经验


1、首先设备尺寸是1280*800,我们打算用rpx来画页面,这边还有个需要注意的地方就是,uniapp官方秉承最大程度上保持界面不失真的策略,“限定了可适配的最大屏幕宽度为960px,在这个范围内,rpx可以根据屏幕宽度缩放。一旦超过960,rpx再根据屏幕宽度缩放就变的没有意义了”(也就是设计稿上的图像会失真)

当然也可以自己去手动设置来调整这个“可适配的最大屏幕宽度”,在page.json文件中加入以下属性,这边以我用到的这个设备为例

page.json文件:

2、 HBuilder开发的话 可以去设置px转rpx提示,这个也很方便,具体设置步骤如下

 

这边根据设计稿去配比就好了,最后设置成功效果如下:

 

最后附上代码,截屏页组件代码如下:

<template><view class="live-camera" :style="{ width: windowWidth, height: windowHeight }"><view class="preview" :style="{ width: windowWidth, height: windowHeight - 10 }"><live-pusher id="livePusher" ref="livePusher" class="livePusher" mode="FHD" beauty="1" whiteness="0":aspect="aspect" min-bitrate="1000" audio-quality="16KHz" device-position="back" :auto-focus="true":muted="true" :enable-camera="true" :enable-mic="false" :zoom="false" @statechange="statechange":style="{ width: cameraWidth, height: cameraHeight }"></live-pusher><live-pusher />< <!--提示语--><cover-view class="remind"><text class="remind-text" style="">{{ message }}</text></cover-view><!--辅助线--><!-- <cover-view class="outline-box" :style="{ width: windowWidth, height: windowHeight - 80 }"><cover-image class="outline-img" src="/static/live-camera/outline/idphoto.png" style=""></cover-image></cover-view> --></view><view class="menu"><!--底部菜单区域背景--><cover-image class="menu-mask" src="/static/live-camera/bar.png"></cover-image><!--返回键--><cover-image class="menu-back" @tap="back" src="/static/live-camera/back.png"></cover-image><!--快门键--><cover-image class="menu-snapshot" @tap="snapshot" src="/static/live-camera/shutter.png"></cover-image><!--反转键--><!-- <cover-image class="menu-flip" @tap="flip" src="/static/live-camera/flip.png"></cover-image> --></view></view>
</template><script>import config from "@/utils/config.js"let _this = null;export default {data() {return {// actions: config.VUE_APP_BASE_API + '/jeecg-boot/fjxhx/file/upload/file',actions: 'http://172.30.1.132:10038/arcface/user/face/get',dotype: 'idphoto', //操作类型message: '', //提示aspect: '2:3', //比例cameraWidth: '', //相机画面宽度cameraHeight: '', //相机画面宽度windowWidth: '', //屏幕可用宽度windowHeight: '', //屏幕可用高度camerastate: false, //相机准备好了livePusher: null, //流视频对象snapshotsrc: null, //快照isStopPreview: false // 关闭视频流,轮询不开启。};},onLoad(e) {_this = this;if (e.dotype != undefined) this.dotype = e.dotype;this.initCamera();},onReady() {this.livePusher = uni.createLivePusherContext('livePusher', this);// this.startPreview(); //开启预览并设置摄像头this.poenCarme();},methods: {//轮询打开poenCarme() {//#ifdef APP-PLUSif (plus.os.name == 'Android') {this.poenCarmeInterval = setInterval(function() {// console.log(_this.camerastate);if (!_this.camerastate) _this.startPreview();}, 2500);}//#endif},//初始化相机initCamera() {uni.getSystemInfo({success: function(res) {_this.windowWidth = res.windowWidth;_this.windowHeight = res.windowHeight;_this.cameraWidth = res.windowWidth;_this.cameraHeight = res.windowWidth / 1.5;}});},//开始预览startPreview() {if (_this.isStopPreview) {return}this.livePusher.startPreview({success: a => {console.log(a);}});},//停止预览stopPreview() {this.livePusher.stopPreview({success: a => {_this.camerastate = false; //标记相机未启动}});},//状态statechange(e) {//状态改变console.log(e);if (e.detail.code == 1007) {_this.camerastate = true;} else if (e.detail.code == -1301) {_this.camerastate = false;}},//返回back() {uni.navigateBack();},//抓拍snapshot() {this.livePusher.snapshot({success: e => {console.log('snapshot123', e)_this.isStopPreview = trueuni.showLoading({title: '上传图片中',mask: true})_this.snapshotsrc = e.message.tempImagePath;_this.stopPreview();const fileInfo = {'fileName': 'wxImg.jpg','fileHash': '1111'}const formData = {// 'file': e,'ct': JSON.stringify(fileInfo)}// this.uploadImg(formData)// returnuni.compressImage({ // 压缩图片src: e.message.tempImagePath,quality: 20,success: res => {console.log('res.tempFilePath', res.tempFilePath)_this.snapshotsrc = res.tempFilePath;this.uploadImg(formData)},fail: res => {console.log(1112)_this.uploadFail()},computed: res => {console.log('res.tempFilePath', res.tempFilePath)// _this.snapshotsrc = res.tempFilePath;// this.uploadImg(formData)}})},error: e => {}});},// 上传图片uploadImg(formData) {console.log('_this.actions11133', _this.actions, _this.snapshotsrc)uni.uploadFile({// url: _this.actions, url: _this.actions,// filePath: _this.snapshotsrc,files: [{uri: _this.snapshotsrc}],name: 'file',formData: formData,success: (uploadFileRes) => {console.log(uploadFileRes, typeof uploadFileRes.data);if (JSON.parse(uploadFileRes.data).code === 200) {let data = JSON.parse(uploadFileRes.data).resultconsole.log('========uploadFileRes', JSON.parse(uploadFileRes.data).result, JSON.parse(uploadFileRes.data).code);_this.setImage(JSON.parse(uploadFileRes.data));_this.isStopPreview = falseuni.hideLoading();// _this.$utils.nnToast('图片上传成功')uni.navigateBack();} else {_this.uploadFail(JSON.parse(uploadFileRes.data).message)}},fail: () => {console.log(1112)_this.uploadFail(JSON.parse(uploadFileRes.data).message)},})},uploadFail(msg) {uni.showLoading({title: msg,mask: true})// _this.$utils.nnToast('图片上传失败')setTimeout(function() {_this.isStopPreview = falseuni.hideLoading();uni.navigateBack();}, 2000);},//反转flip() {this.livePusher.switchCamera();},//如果人脸识别成功 则带参数返回上一页进行签到setImage(data) {console.log('------------------setImage(data) ', data, );uni.$emit('setImage', {// path: _this.snapshotsrc,// dotype: this.dotype,userId: data.result.userId})//直接调用上一个页面的setImage()方法,把数据存到上一个页面中去// let pages = getCurrentPages();// let prevPage = pages[pages.length - 2]; //上一个页面// prevPage.setImage({// 	path: _this.snapshotsrc,// 	dotype: this.dotype,// 	imgId: imgId// });}}};
</script><style scoped lang="scss">.live-camera {.preview {justify-content: center;align-items: center;.outline-box {position: absolute;top: 0;left: 0;bottom: 0;z-index: 99;align-items: center;justify-content: center;.outline-img {width: 750px;// height: 1125rpx;}}.remind {position: absolute;top: 880rpx;width: 750rpx;z-index: 100;align-items: center;justify-content: center;.remind-text {color: #dddddd;font-weight: bold;}}}.menu {position: absolute;left: 0;bottom: 0;width: 750rpx;height: 60rpx;z-index: 98;align-items: center;justify-content: center;.menu-mask {position: absolute;left: 0;bottom: 0;width: 750rpx;height: 80rpx;z-index: 98;}.menu-back {position: absolute;left: 30rpx;bottom: 0rpx;width: 60rpx;height: 60rpx;z-index: 99;align-items: center;justify-content: center;}.menu-snapshot {width: 60rpx;height: 60rpx;z-index: 999999;position: absolute;bottom: 0rpx;}.menu-flip {position: absolute;right: 30rpx;bottom: 0rpx;width: 80rpx;height: 80rpx;z-index: 99;align-items: center;justify-content: center;}}}
</style>

这篇关于uniapp---app端人脸识别组件(宽屏版1280*800组件,需手动截屏拍人脸识别,踩坑,成长)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/426334

相关文章

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

基于Qt Qml实现时间轴组件

《基于QtQml实现时间轴组件》时间轴组件是现代用户界面中常见的元素,用于按时间顺序展示事件,本文主要为大家详细介绍了如何使用Qml实现一个简单的时间轴组件,需要的可以参考下... 目录写在前面效果图组件概述实现细节1. 组件结构2. 属性定义3. 数据模型4. 事件项的添加和排序5. 事件项的渲染如何使用

macOS怎么轻松更换App图标? Mac电脑图标更换指南

《macOS怎么轻松更换App图标?Mac电脑图标更换指南》想要给你的Mac电脑按照自己的喜好来更换App图标?其实非常简单,只需要两步就能搞定,下面我来详细讲解一下... 虽然 MACOS 的个性化定制选项已经「缩水」,不如早期版本那么丰富,www.chinasem.cn但我们仍然可以按照自己的喜好来更换

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

vue2 组件通信

props + emits props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新) props检查属性 属性名类型描述默认值typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean,

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除

uniapp设置微信小程序的交互反馈

链接:uni.showToast(OBJECT) | uni-app官网 (dcloud.net.cn) 设置操作成功的弹窗: title是我们弹窗提示的文字 showToast是我们在加载的时候进入就会弹出的提示。 2.设置失败的提示窗口和标签 icon:'error'是设置我们失败的logo 设置的文字上限是7个文字,如果需要设置的提示文字过长就需要设置icon并给

基于SpringBoot的宠物服务系统+uniapp小程序+LW参考示例

系列文章目录 1.基于SSM的洗衣房管理系统+原生微信小程序+LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统+LW参考示例 3.基于SpringBoot+Vue的企业人事管理系统+LW参考示例 4.基于SSM的高校实验室管理系统+LW参考示例 5.基于SpringBoot的二手数码回收系统+原生微信小程序+LW参考示例 6.基于SSM的民宿预订管理系统+LW参考示例 7.基于