APP自定义身份证相机(Android +iOS)

基本上同时兼容安卓和苹果的插件都需要付费,这里我找了2个好用的免费插件

1.仅支持安卓:自定义身份证相机(支持蒙版自定义),内置蒙版,照片预览,身份证裁剪 - DCloud 插件市场、

2.支持iOS(已测),支持Android(未测,应该也可以用):

 自定义相机 - DCloud 插件市场

第一个插件使用方法(仅支持安卓):

创建一个realName.vue文件

<view class="personalInfo" style="margin-top: 20rpx;"><view class="label" style="margin-bottom: 8rpx;"><view class="blue"></view><view class="title">证件图片</view></view><view class="tips">请拍摄或上传身份证原件照片,确保照片完整清晰</view><view class="imgBox"><view class="front"><image :src="frontImg" :class="platform == 'ios' ? 'transformImg' : ''" @click="uploadImgNew('front')"/><view class="frontBtn" @click="uploadImgNew('front')" v-if="frontImg == ''">上传人像面</view></view><view class="back"><image :src="backImg" :class="platform == 'ios' ? 'transformImg' : ''" @click="uploadImgNew('back')"/><view class="backBtn" @click="uploadImgNew('back')" v-if="backImg == ''">上传国徽面</view></view></view></view>
export default {data () {return {frontImg: '',backImg: '',canvasSiz:{width:188,height:273},flag: true}},
methods:{uploadImgNew(types){console.log('打开相机');let platform = uni.getSystemInfoSync().platformif(!this.flag){uni.showToast({title: '图片正在上传中,请误做其他操作', icon: 'none'})return}if(platform == 'ios'){// ios的另外用了别的插件,下面会讲到uni.navigateTo({url: `./idcard?dotype=${types == 'front' ? 'face' : 'badge'}`})}else{var cameraModule = uni.requireNativePlugin('yun-camerax-module');//无需蒙版可将type设置为非参数值,例如 type:99cameraModule.takePhoto({ type: types == 'front' ? 0 : 1, imageIndex: 2, fullSrc: true,text: types == 'front' ? '将身份证正面置于此区域内并对齐边缘' : '将身份证背面置于此区域内并对齐边缘'}, res => {console.log(res);uni.showModal({title: '提示',// content: JSON.stringify(res),content: '请再次确认使用该图',success: (res1) => {if (res1.confirm) {console.log('用户点击确定',res);this.upLoadImg(res.file,types)} else if (res1.cancel) {console.log('用户点击取消');}}});});}},async upLoadImg(path,type) {setTimeout(()=>{uni.showToast({title: '上传中',icon: 'none'})this.flag = falseuni.uploadFile({url: 'xxxxxx/upload', //后端上传接口filePath: path,name: "file",success: (res) => {console.log('res222',res);if(JSON.parse(res.data).code == 0){console.log('JSON.parse(res.data)',JSON.parse(res.data));if(type == 'front'){this.frontImg = JSON.parse(res.data).data.rel_paththis.$forceUpdate()}else{this.backImg = JSON.parse(res.data).data.rel_paththis.$forceUpdate()}this.flag = true   }else{uni.showToast({title: JSON.parse(res.data).msg,icon: 'none'})}},fail(e) {this.showTip("上传图片失败");},});},300)}, 

第二个插件使用方法:

需要用到live-pusher直播推流,在manifest.json中勾选,真机调试需要重新打自定义基座再重新运行

为了防止样式兼容问题,另外需配置如下:

在同级目录下创建idcard.nvue文件

然后把下面代码整个copy进去

<template><view class="live-camera" :style="{ width: windowWidth, height: windowHeight }"><view class="preview" :style="{ width: windowWidth, height: windowHeight - 65 }"><live-pusherid="livePusher"ref="livePusher"class="livePusher"mode="FHD"beauty="0"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><!--提示语--><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-imageclass="outline-img":src="dotype == 'face' ? '/static/live-camera/outline/idcardface.png' : '/static/live-camera/outline/idcardbadge.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>
let _this = null;
export default {data() {return {poenCarmeInterval: null, //打开相机的轮询dotype: 'face', //操作类型message: '', //提示aspect: '2:3', //比例cameraWidth: '', //相机画面宽度cameraHeight: '', //相机画面宽度windowWidth: '', //屏幕可用宽度windowHeight: '', //屏幕可用高度camerastate: false, //相机准备好了livePusher: null, //流视频对象snapshotsrc: null //快照};},onLoad(e) {console.log('e',e);_this = this;this.dotype = e.dotype;this.initCamera();},onReady() {uni.showToast({title: '相机加载中...',icon: 'none',duration: 800})this.livePusher = uni.createLivePusherContext('livePusher', this);console.log('this.livePusher',this.livePusher);this.startPreview(); //开启预览并设置摄像头this.poenCarme();},methods: {//轮询打开poenCarme() {//#ifdef APP-PLUSif (plus.os.name == 'Android') {console.log('111');this.poenCarmeInterval = setInterval(function() {console.log(_this.camerastate);if (!_this.camerastate) _this.startPreview();}, 2500);}else{console.log('2222');}//#endif},//初始化相机initCamera() {//处理安卓手机异步授权问题uni.getSystemInfo({success: (res) => {console.log('resxxxx',res);this.windowWidth = res.windowWidth;this.windowHeight = res.windowHeight;this.cameraWidth = res.windowWidth;this.cameraHeight = res.windowWidth * 1.5;}});},//开始预览startPreview() {console.log('执行开始预览');this.livePusher.startPreview({success: (a) => {console.log('aaa',a);}});},//停止预览stopPreview() {this.livePusher.stopPreview({success: a => {console.log('停止预览',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('快门',e);this.snapshotsrc = e.message.tempImagePath;this.stopPreview();this.setImage();uni.navigateBack();}});},//反转flip() {this.livePusher.switchCamera();},//设置setImage() {let pages = getCurrentPages();let prevPage = pages[pages.length - 2]; //上一个页面//直接调用上一个页面的setImage()方法,把数据存到上一个页面中去prevPage.$vm.setImage({ path: this.snapshotsrc, dotype: this.dotype });}}
};
</script><style 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: 750rpx;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: 180rpx;z-index: 98;align-items: center;justify-content: center;.menu-mask {position: absolute;left: 0;bottom: 0;width: 750rpx;height: 180rpx;z-index: 98;}.menu-back {position: absolute;left: 30rpx;bottom: 50rpx;width: 80rpx;height: 80rpx;z-index: 99;align-items: center;justify-content: center;}.menu-snapshot {width: 130rpx;height: 130rpx;z-index: 99;}.menu-flip {position: absolute;right: 30rpx;bottom: 50rpx;width: 80rpx;height: 80rpx;z-index: 99;align-items: center;justify-content: center;}}
}</style>

因为第一次使用nvue,代码整个都成灰色,需要在vscode设置中按下图配置,代码就会和.vue文件一样变彩色,方便阅读

在realName.vue文件中加入:

<canvas id="canvas-clipper" canvas-id="canvas-clipper" type="2d" :style="{width: canvasSiz.width+'px',height: canvasSiz.height+'px',position: 'absolute',left:'-500000px',top: '-500000px'}" />

这里用到canvas是为了把live-pusher横屏拍摄的身份证裁剪

methods:{//设置图片setImage(e) {console.log('跳回这个页面',e);let type = e.dotype == 'face' ? 'front' : 'back'//显示在页面console.log('type',type);// this.upLoadImg(e.path,type)this.zjzClipper(e.path,type)},//证件照裁切zjzClipper(path,type) {uni.getImageInfo({src: path,success: (image) => {console.log('image',image);this.canvasSiz.width =188;this.canvasSiz.height =273;//因为nvue页面使用canvas比较麻烦,所以在此页面上处理图片let ctx = uni.createCanvasContext('canvas-clipper', this);ctx.drawImage(path,parseInt(0.15 * image.width),parseInt(0.17 * image.height),parseInt(0.69 * image.width),parseInt(0.65 * image.height),0,0,188,273);ctx.draw(false, () => {uni.canvasToTempFilePath({destWidth: 188,destHeight: 273,canvasId: 'canvas-clipper',fileType: 'jpg',success: (res) => {// this.savePhoto(res.tempFilePath);// this.frontImg = res.tempFilePaththis.upLoadImg(res.tempFilePath,type)}},this);});}});},

如果想保存拍摄的照片还可以使用下面方法

savePhoto(path){this.imagesrc = path;//保存到相册uni.saveImageToPhotosAlbum({filePath: path,success: () => {uni.showToast({title: '已保存至相册',duration: 2000});}});},

realName.vue的css样式部分

.personalInfo{padding: 27rpx 30rpx;box-sizing: border-box;background-color: #fff;.label{display: flex;align-items: center;margin-bottom: 50rpx;.blue{width: 8rpx;height: 30rpx;background-color: #3E71FE;margin-right: 12rpx;}.title{font-weight: 500;font-size: 32rpx;color: #1D1B1A;}}.realName{display: flex;align-items: center;margin-bottom: 30rpx;padding-left: 20rpx;box-sizing: border-box;.name{font-weight: 500;font-size: 28rpx;color: #1D1B1A;}}.tips{font-weight: normal;font-size: 24rpx;color: #929292;margin-bottom: 30rpx;}.lineBottom{width: 650rpx;height: 2rpx;background: #F5F5F5;margin: auto;margin-bottom: 30rpx;}.imgBox{display: flex;flex-direction: column;justify-content: space-between;padding: 0 82rpx;box-sizing: border-box;.front{position: relative;width: 526rpx;height: 288rpx;border-radius: 20rpx 20rpx 20rpx 20rpx;margin-bottom: 28rpx;background: url('https://res.qyjpay.cn/static/res/yewuban-smrz-zhengmian.png') no-repeat center;background-size: contain;.frontBtn{position: absolute;bottom: 50rpx;left: 123rpx;width: 280rpx;height: 90rpx;line-height: 90rpx;background: #3E71FE;box-shadow: 0rpx 8rpx 12rpx 1rpx rgba(62,113,254,0.15);border-radius: 45rpx 45rpx 45rpx 45rpx;font-size: 32rpx;color: #FFFFFF;font-weight: normal;text-align: center;}image{position: absolute;left: 0;top: 0;width: 526rpx;height: 288rpx;border-radius: 20rpx 20rpx 20rpx 20rpx;}}.transformImg{position: absolute;left: 120rpx !important;top: -120rpx !important;transform: rotate(-90deg);width: 288rpx !important;height: 526rpx !important;z-index: 999;}.back{position: relative;width: 526rpx;height: 288rpx;border-radius: 20rpx 20rpx 20rpx 20rpx;background: url('https://res.qyjpay.cn/static/res/yewuban-smrz-fanmian.png') no-repeat center;background-size: contain;.backBtn{position: absolute;bottom: 50rpx;left: 123rpx;width: 280rpx;height: 90rpx;line-height: 90rpx;background: #3E71FE;box-shadow: 0rpx 8rpx 12rpx 1rpx rgba(62,113,254,0.15);border-radius: 45rpx 45rpx 45rpx 45rpx;font-size: 32rpx;color: #FFFFFF;font-weight: normal;text-align: center;}image{position: absolute;left: 0;top: 0;width: 526rpx;height: 288rpx;border-radius: 20rpx 20rpx 20rpx 20rpx;}}}}

里面的图片和结构根据项目需求自行修改

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/315051.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Unity】AssetBundle加载与卸载

unity官方apiAssetBundle-LoadFromFileAsync - Unity 脚本 API 异步加载AB包 using UnityEngine; using System.Collections; using System.IO;public class LoadFromFileAsyncExample : MonoBehaviour {IEnumerator Start(){var bundleLoadRequest AssetBundle.LoadFromFil…

区块链安全应用------压力测试

测试要求&#xff1a; 1. 对以下AccountManager智能合约进行压测(基础要求set函数测试&#xff0c;balanceOf涵为20分加分项)2. 在本地链进行测试&#xff0c;需要监控本地进程的资源使用情况。每个进程的multiOutput属性为Avg3. 需要将每一个更改的配置文件截图&#xff0c;和…

深度解析 Spring 源码:三级缓存机制探究

文章目录 一、 三级缓存的概述二、 三级缓存的实现原理2.1 创建Bean流程图2.2 getBean()2.3 doGetBean()2.4 createBean()2.5 doCreateBean()2.4 getSingleton() 三、 三级缓存的使用场景与注意事项3.1 在实际开发中如何使用三级缓存3.2 三级缓存可能出现的问题及解决方法 一、…

【服务器部署篇】Linux下Ansible安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

不可重复读,幻读和脏读

不可重复读一般在读未提交&#xff0c;读已提交这两种隔离级别出现&#xff0c;第一次读和第二次读的数据不一致。 幻读一般在读未提交&#xff0c;读已提交&#xff0c;可重复读出现&#xff0c;原因是第一个事务执行时&#xff0c;第二个事务完成了提交&#xff0c;在第一个…

CISSP通关学习笔记:共计 9 个章节(已完结)

1. 笔记说明 第 0 章节为开篇介绍&#xff0c;不包括知识点。第 1 - 8 章节为知识点梳理汇总&#xff0c;8 个章节的知识框架关系如下图所示&#xff1a; 2. 笔记目录 「 CISSP学习笔记 」0.开篇「 CISSP学习笔记 」1.安全与风险管理「 CISSP学习笔记 」2.资产安全「 CISSP…

网络安全实训Day15

写在前面 电子垃圾&#xff0c;堂堂恢复连载。本来不想分天数梳理了&#xff0c;但是最后要写实训报告&#xff0c;报告里还要有实训日记记录每日学的东西&#xff0c;干脆发这里留个档&#xff0c;到时候写报告提供一个思路。 网络空间安全实训-渗透测试 渗透测试概述 定义 一…

react引入iconfont的svg图标

react引入iconfont的svg图标 本文目录 react引入iconfont的svg图标普通图标通过link引入css组件内引入css使用 svg图标通过script引入js组件内引入js使用 通过封装组件自定义封装组件中调用 通过antd封装使用 普通图标 通过link引入css <link rel"stylesheet" h…

Labelme安装和使用

简介&#xff1a;labelme是图形图像注释工具&#xff0c;它是用Python编写的&#xff0c;并将Qt用于其图形界面&#xff0c;是麻省理工&#xff08;MIT&#xff09;的计算机科学和人工智能实验室&#xff08;CSAIL&#xff09;研发的图像标注工具&#xff0c;人们可以使用该工具…

【微信小程序调用百度API实现图像识别实战】-前后端加强版

前言&#xff1a;基于前面两篇图像识别项目实战文章进行了改造升级。 第一篇 入门【微信小程序调用百度API实现图像识别功能】----项目实战 第二篇 前后端结合 【微信小程序调用百度API实现图像识别实战】----前后端分离 这一篇主要讲述的是在第二篇的基础上新增意见反馈功能&a…

QFD赋能人工智能:打造智能化需求分析与优化新纪元

在科技飞速发展的今天&#xff0c;人工智能(AI)已经渗透到我们生活的方方面面。然而&#xff0c;如何让AI更加贴合用户需求&#xff0c;提供更加精准和个性化的服务&#xff1f;这成为了一个亟待解决的问题。质量功能展开&#xff08;Quality Function Deployment&#xff0c;简…

go设计模式之工厂方法模式

工厂方法模式 什么是工厂方法模式 工厂方法模式是一种创建型设计模式&#xff0c;它定义了一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化推迟到其子类。 这个接口就是工厂接口&#xff0c;子类就是具体工厂类&#xff0c;而需要创…

Android 开发工具使用

c调试 在NDK调试的时候&#xff0c;如果找不到 符号的话&#xff0c;我们可以在调试配置中添加符号地址的全路径一直到根目录&#xff1a;&#xff0c;xxx/armeabi-v7a&#xff1a; You must point the symbol search paths at the obj/local/ directory. This is also not a …

黑盒优化系列(一):自动化提示词优化【一、绪论】

大语言模型的提示词 随着ChatGPT等大语言模型的问世&#xff0c;我们获取知识的方式从单一的搜索引擎如Google转变为类似ChatGPT这种通过 Q & A 方式提供的方法。 我们尝试对比一下不同提示词&#xff0c;对应的模型输出 ChatGPT无提示词 API&#xff1a; ChatGPT 3.5 …

解决HttpServletRequest中的InputStream/getReader只能被读取一次的问题

一、事由 由于我们业务接口需要做签名校验&#xff0c;但因为是老系统了签名规则被放在了Body里而不是Header里面&#xff0c;但是我们不能在每个Controller层都手动去做签名校验&#xff0c;这样不是优雅的做法&#xff0c;然后我就写了一个AOP&#xff0c;在AOP中实现签名校…

mysql-sql-练习题-2-窗口函数

窗口函数 访问量max sum建表窗口函数连接 直播间人数 第1、3名建表排名sum 访问量max sum 每个用户截止到每月为止&#xff0c;最大单月访问次数&#xff0c;累计到该月的总访问次数 建表 create table visit(uid1 varchar(5) comment 用户id,month1 varchar(10) comment 月…

Rust 实战练习 - 12. Axum Web 简单demo

Rust Web 历程 Rust 的异步框架tokio非他莫属&#xff0c;而web框架一直是悬而未决&#xff0c;说到底还是因为没有官方成熟的方案指引&#xff0c;大家各玩各的&#xff0c;互不兼容&#xff0c;白白浪费精力。 这个事情一直等到半官方组织tokio推出axum有了改善。但是市场上…

Python赋值运算符

目录 赋值运算符 将值赋给变量&#xff1a; 做加法运算之后完成赋值&#xff1a; 做减法运算之后完成赋值&#xff1a;- 做乘法运算之后完成赋值&#xff1a;* 做除法运算之后完成赋值&#xff1a;/ 做整除运算之后完成赋值&#xff1a;// 做幂次运算之后完成赋值&#xff1a;*…

西湖大学赵世钰老师【强化学习的数学原理】学习笔记2节

强化学习的数学原理是由西湖大学赵世钰老师带来的关于RL理论方面的详细课程&#xff0c;本课程深入浅出地介绍了RL的基础原理&#xff0c;前置技能只需要基础的编程能力、概率论以及一部分的高等数学&#xff0c;你听完之后会在大脑里面清晰的勾勒出RL公式推导链条中的每一个部…

基于FastGPT搭建知识库问答系统

什么是 FastGPT &#xff1f; FastGPT 是一个基于 LLM 大语言模型的知识库问答系统&#xff0c;提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排&#xff0c;从而实现复杂的问答场景&#xff01; FastGPT 允许用户构建本地知识库&#xff0c;…