本文为uni-app接入百度OCR识别身份证号,话不多说,直接上代码:
1. 第一步注册百度智能云账号,选择文字识别,创建应用,获取Api Key 与 Secret Key(下面要用到):
2.第二步,查看百度OCR身份证识别技术文档,如下,共需调用2个接口:
第一接口:获取百度access_token, 上代码:
getBDtoken() {
uni.showLoading({
title: '正在连接服务...'
})
return new Promise(resolve => {
uni.request({
url: 'https://aip.baidubce.com/oauth/2.0/token', // 百度获取token接口地址
data: {
'grant_type': 'client_credentials', // 固定写死
'client_id': '你上面申请获取的API Key',
'client_secret': '你上面申请的Secret Key'
},
method: 'GET',
success(res) {
resolve(res)
},
fail(e) {
uni.hideLoading()
Modal.toast('连接服务出错,请稍后再试!')
}
})
})
}
第二个接口先不要着急,请继续往下看:
3.百度OCR的第二个接口入参需要图像信息,这个图像信息怎么获取呢?上代码:
takePhoto() {
// 直接调用uni-app现有API, 爽翻天
const ctx = uni.createCameraContext()
ctx.takePhoto({
quality: 'high',
success: async res => {
let path = res.tempImagePath // 拍照的临时地址
// 这里用百度ORC身份识别的image参数,需要转成base64格式
let base64String = `${wx.getFileSystemManager().readFileSync(path, "base64")}`
},
fail: err => {
uni.hideLoading()
Modal.toast('生成图片错误, 请稍后重试!')
}
})
},
4.好了,到这里就可以调用百度OCR的第二个接口了,上代码:
// 参数准备
// const params = {
// access_token: data.data.access_token,
// data: {
// image: base64String,
// id_card_side: 'front'
// }
// }
// 这个接口才是真正的识别身份证,上面准备的access_token,base64String都为此准备
getIdCard(params) {
uni.showLoading({
title: '正在解析...'
})
return new Promise(resolve => {
uni.request({
// 身份证识别接口
url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=' + params.access_token,
data: params.data,
method: 'POST',
header: {
"Content-Type": "application/x-www-form-urlencoded"
},
success(res) {
uni.hideLoading()
resolve(res)
},
fail(e) {
uni.hideLoading()
Modal.toast('解析出错,请稍后再试!')
},
complete() {
}
})
})
},
5.效果图:
6.完整代码,可以直接拿去用,不喜欢样式的自行修改:
<template>
<view class="container">
<camera device-position="back" flash="auto" @error="error" class="camera">
<cover-view class="cover-view">
<cover-view class="cover-view-top"></cover-view>
<cover-view class="scan-img-view">
<cover-image src="../../static/img/idCard/scan-img.png" class="scan-img" id="scanImg"></cover-image>
<cover-view class="tips">
<cover-view>{{tips}}</cover-view>
</cover-view>
</cover-view>
<cover-view class="cover-view-bot">
<cover-image src="../../static/img/idCard/takePhoto.png" class="take-img" @click="takePhoto"></cover-image>
</cover-view>
<cover-view class="id-card-info" v-if="dialogVisible">
<cover-view class="middle">
<cover-view class="title">识别结果</cover-view>
<cover-view class="content">
<cover-view class="item">
<cover-view class="label">姓名: </cover-view>
<cover-view class="value">{{cradInfo.name}}</cover-view>
</cover-view>
<cover-view class="item">
<cover-view class="label">出生日期: </cover-view>
<cover-view class="value">{{cradInfo.birthdate}}</cover-view>
</cover-view>
<view class="item">
<cover-view class="label">性别: </cover-view>
<cover-view class="value">{{cradInfo.sex === '801' ? '男':'女'}}</cover-view>
</view>
<view class="item">
<cover-view class="label">身份证号: </cover-view>
<cover-view class="value">{{cradInfo.idNo}}</cover-view>
</view>
</cover-view>
<cover-view class="footer">
<cover-view class="btn sure">确认信息</cover-view>
<cover-view class="btn cancel" @click="closeDialog">重新识别</cover-view>
</cover-view>
</cover-view>
</cover-view>
</cover-view>
</camera>
</view>
</template>
<script>
let t
export default {
data() {
return {
cradInfo: {},
dialogVisible: false,
tips: '请将身份证置于拍照区域拍照'
}
},
onShow() {
const timer = setTimeout(() => {
this.setTipsStatus()
clearTimeout(timer)
}, 1000)
},
methods: {
setTipsStatus() {
let num = 0
t = setInterval(() => {
num++
if (num > 4) {
num = 0
}
this.tips = '请将身份证置于拍照区域拍照' + '....'.substring(0, num)
}, 1000)
},
takePhoto() {
const ctx = uni.createCameraContext()
ctx.takePhoto({
quality: 'high',
success: async res => {
this.drawCanvas(res.tempImagePath)
},
fail: err => {
uni.hideLoading()
uni.showToast({
title: '生成图片错误, 请稍后重试!'
})
}
})
},
drawCanvas(path) {
uni.showLoading({
title: '正在生成图片...'
})
let base64String = `${wx.getFileSystemManager().readFileSync(path, "base64")}`
this.getBDtoken().then(data => {
const params = {
access_token: data.data.access_token,
data: {
image: base64String,
id_card_side: 'front'
}
}
this.getIdCard(params).then(res => {
if (res) {
const result = res.data.words_result
this.cradInfo = {
idNo: result['公民身份号码'] ? result['公民身份号码'].words : '',
name: result['姓名'] ? result['姓名'].words : '',
sex: result['性别'] ? (result['性别'].words === '男' ? '801' : '802') : '801',
birthdate: result['出生'] ? (result['出生'].words.substring(0, 4) + '-' + result['出生'].words.substring(4, 6) + '-' + result['出生'].words.substring(6, 8)) : '',
}
this.dialogVisible = true
}
})
})
},
getBDtoken() {
uni.showLoading({
title: '正在连接服务...'
})
return new Promise(resolve => {
uni.request({
url: 'https://aip.baidubce.com/oauth/2.0/token',
data: {
'grant_type': 'client_credentials',
'client_id': '你申请的API Key',
'client_secret': '你申请的Secret Key'
},
method: 'GET',
success(res) {
resolve(res)
},
fail(e) {
uni.hideLoading()
uni.showToast({
title: '连接服务出错,请稍后再试!'
})
}
})
})
},
getIdCard(params) {
uni.showLoading({
title: '正在解析...'
})
return new Promise(resolve => {
uni.request({
url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=' + params.access_token,
data: params.data,
method: 'POST',
header: {
"Content-Type": "application/x-www-form-urlencoded"
},
success(res) {
uni.hideLoading()
resolve(res)
},
fail(e) {
uni.hideLoading()
uni.showToast({
title: '解析出错,请稍后再试!'
})
},
complete() {
}
})
})
},
error(e) {
console.log(e.detail);
},
closeDialog() {
this.dialogVisible = false
this.cradInfo = {}
}
}
}
</script>
<style lang="scss" scoped>
.container{
position: relative;
}
.camera {
position: absolute;
top: 0;
left: 0;
z-index: 99;
width: 750upx;
height: 100%;
}
.cover-view {
width: 750upx;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.cover-view-top {
width: 750upx;
height: 200upx;
background-color: rgba(0, 0, 0, .4);
}
.cover-view-bot {
flex: 1;
width: 750upx;
background-color: rgba(0, 0, 0, .4);
display: flex;
justify-content: center;
align-items: center;
.take-img {
width: 120upx;
height: 120upx;
}
}
.canvas{
position: absolute;
top: 240upx;
left: 45upx;
height: 410upx;
width: 660upx;
}
.scan-img-view{
position: relative;
.scan-img {
opacity: 0.4;
width: 100%;
height: 500upx;
}
.tips{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
font-size: $uni-font-size-sm;
}
}
.id-card-info{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, .8);
z-index: 999999 !important;
.middle{
width: 550upx;
height: 600upx;
background-color: #ffffff;
border-radius: 20upx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.title{
font-size: $uni-font-size-maxer;
height: 100upx;
line-height: 100upx;
text-align: center;
font-weight: bold;
}
.content{
flex: 1;
width: 100%;
padding-left: 50upx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
.item{
display: flex;
margin-bottom: 20upx;
font-size: $uni-font-size-lger;
.label{
color: $uni-text-color-grey;
}
.value{
margin-left: 10upx;
}
}
}
.footer{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20upx;
.btn{
width: 450upx;
height: 80upx;
border-radius: 60upx;
line-height: 80upx;
text-align: center;
}
.sure{
color: #ffffff;
background-color: $uni-bg-color-global;
margin-bottom: 20upx;
}
.cancel{
color: grey;
background-color: $uni-bg-color-grey;
}
}
}
}
</style>
有小伙伴私信我要图片,安排: