1、场景介绍
什么情况下需要用到小程序的QCR技术,无非是身份证/银行卡等信息的图片识别场景下需要用到。下文介绍QCR在微信小程序中的功能实现。下文主要讲解微信小程序QCR插件识别
2、使用微信开发接口实现
【注意】因为是服务端的接口,所以做好是放在后端做请求,因为放在前端容易暴露APPID和AppSecret,有风险的
微信小程序开发者文档:developers.weixin.qq.com/miniprogram…
- 首先获取access_token
官方文档:developers.weixin.qq.com/miniprogram…
示例代码
/**
* @description: 获取access_token,用于证件识别
* @param {小程序的appID} APPID
* @param {输入AppSecret} AppSecret
* @return {获取access_token}
*/
getAccessToken(APPID = 'APPID', AppSecret = 'AppSecret') {
return new Promise((resolve, reject) => {
wx.request({
method: 'get',
url: `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${AppSecret}`,
success(res) {
resolve(res)
},
fail(res) {
reject(res)
}
})
})
}
- 调用QCR证件识别方法
官方文档:developers.weixin.qq.com/miniprogram…
/**
* @description: 微信小程序服务端api调用识别身份证
* 官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/ocr/ocr.idcard.html
* @param {生成的accessToken} accessToken
* @param {输入金额值, string} img_url 要检测的图片 url,传这个则不用传 img 参数。
* @param {输入金额值, FormData} img form-data 中媒体文件标识,有filename、filelength、content-type等信息,传这个则不用传 img_url。
* @return {获取access_token}
*/
idCardQCR(accessToken, img_url, img) {
return new Promise((resolve, reject) => {
wx.request({
method: 'post',
url: `https://api.weixin.qq.com/cv/ocr/idcard?type=MODE&img_url=${img_url}&access_token=${accessToken}`,
success(res) {
console.log('识别证件',res)
if (res.errMsg === "request:ok") {
resolve(res.data)
} else {
wx.showToast({
title: '获取access_token失败!',
icon: 'none'
})
}
},
fail(res) {
wx.showToast({
title: '获取access_token失败!',
icon: 'none'
})
reject(res)
}
})
})
}
请求失败:
原因是
我们需要区微信服务平台去购买免费的100次/天:fuwu.weixin.qq.com/service/det…
OCR识别案例: developers.weixin.qq.com/community/d…
识别成功
整体代码为:
/**
* @description: 获取access_token,用于证件识别
* @param {小程序的appID} APPID
* @param {输入AppSecret} AppSecret
* @return {获取access_token}
*/
getAccessToken(APPID = 'APPID', AppSecret = 'AppSecret') {
return new Promise((resolve, reject) => {
wx.request({
method: 'get',
url: `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${AppSecret}`,
success(res) {
if (res.errMsg === "request:ok") {
resolve(res.data)
} else {
wx.showToast({
title: '获取access_token失败!',
icon: 'none'
})
}
},
fail(res) {
wx.showToast({
title: '获取access_token失败!',
icon: 'none'
})
reject(res)
}
})
})
},
/* 身份证---正反面 */
// 正面: http://3pl.dekuncn.com//upload/2021-12-22/20211222030944214AH90TN8.jpg
// 反面: http://3pl.dekuncn.com//upload/2021-12-15/2021121504002872RJBKDEFO.jpg
/* 驾驶证 */
// http://3pl.dekuncn.com//upload/2021-12-22/2021122203124441CS8EOW7P.jpg
/* 行驶证 */
// http://3pl.dekuncn.com//upload/2021-12-22/2021122203123967IT9U0XBO.jpg
/* 银行卡 */
// https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13770567688%2F641.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1642750676&t=605fb88baf0b654fe3badfcad7937104
/**
* @description: 微信小程序服务端api调用识别身份证
* 官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/ocr/ocr.idcard.html
* @param {生成的accessToken} accessToken
* @param {识别的证件类型, bankcard :银行卡号; bizlicense:营业执照 OCR 识别; drivinglicense:驾驶证 OCR 识别; :身份证 OCR 识别;comm :小程序的通用印刷体 OCR 识别; driving:程序的行驶证 OCR 识别} type
* @param {输入金额值, string} img_url 要检测的图片 url,传这个则不用传 img 参数。 上传到服务器转成链接图片的识别
* @param {输入金额值, FormData} img form-data 中媒体文件标识,有filename、filelength、content-type等信息,传这个则不用传 img_url。 本地文件识别【按道理来说这个是比较合理的】
* @return {获取access_token}
*/
idCardQCR(accessToken, img_url, type = 'idcard') {
return new Promise((resolve, reject) => {
wx.request({
method: 'post',
url: `https://api.weixin.qq.com/cv/ocr/${type}?type=MODE&img_url=${img_url}&access_token=${accessToken}`,
success(res) {
console.log('识别证件', res)
if (res.errMsg === "request:ok") {
resolve(res.data)
} else {
wx.showToast({
title: '获取access_token失败!',
icon: 'none'
})
}
},
fail(res) {
wx.showToast({
title: '获取access_token失败!',
icon: 'none'
})
reject(res)
}
})
})
}
页面调用:
app.commonModel.common.getAccessToken().then(responce => {
console.log('页面请求成功', responce)
app.commonModel.common.idCardQCR(responce.access_token, 'http://3pl.dekuncn.com//upload/2021-12-22/2021122203435670RVNIITYN.jpg','bankcard')
})
【注意】前端存放appID和AppSecret的风险是,我们借助解除跨域限制的谷歌浏览器【推荐文章:前端浏览器跨域问题】,也同样可以实现其接口调用,这就导致了一个问题就是如果是其他人拿到了这些信息,就会引发问题
3、 借助腾讯云AI开放平台实现证件识别【种类多,识别度高】
官网:ai.qq.com/
腾讯云官网:cloud.tencent.com/act
【注意】这里都是后端的工作,所以前端了解一下就可以了。如果要做成跨平台通用方式的QCR识别,需要后端给你识别接口,然后应用于各端
4、 使用小程序云函数进行证件识别
参考文章: 微信小程序-云函数-OCR识别
5、 使用小程序QCR插件进行证件识别
【注意】此插件需要有摄像头的手机设备才可使用 效果为:
1、 app.json文件中使用
"plugins": {
"ocr-plugin": {
"version": "3.1.2",
"provider": "wx4418e3e031e551be"
}
}
2、 页面中使用
cardIdentify.wxml 文件
<!-- 小程序QCR插件 -->
<headTitle title='小程序QCR插件'>
<view class="paddingLeftRight16 paddingBtm16 " slot='content'>
<view class="content-title">
插件文档:<text data-copyData='{{QCRPluginDoc}}' bindtap="copyAiText" class="hrefCss">{{ QCRPluginDoc }}</text>
</view>
<view class="content-title">
通用印刷体QCR,此插件不支持。可以使用云函数开发
</view>
<view class="margin-top">
<ocr-navigator bind:onSuccess="QCRFontIdCard" certificateType="idCard" opposite="{{false}}">
<button type="primary" class="marginBtm5">身份证正面识别</button>
</ocr-navigator>
<ocr-navigator bind:onSuccess="QCRBackIdCard" certificateType="idCard" opposite="{{true}}">
<button type="primary" class="marginBtm5">身份证反面识别</button>
</ocr-navigator>
<ocr-navigator bind:onSuccess="QCRBanksuccess" certificateType="bankCard">
<button type="primary" class="marginBtm5">银行卡识别</button>
</ocr-navigator>
<ocr-navigator bind:onSuccess="QCRDriverSuccess" certificateType="drivingLicense" selectedOptions="{{['plateNum','vehicleType','owner']}}">
<button type="primary" class="marginBtm5">行驶证识别</button>
</ocr-navigator>
<ocr-navigator bind:onSuccess="QCRDriverLicenseSuccess" certificateType="driverslicense">
<button type="primary" class="marginBtm5">驾驶证识别</button>
</ocr-navigator>
<ocr-navigator bind:onSuccess="QCRBusinessSuccess" certificateType="businessLicense">
<button type="primary" class="marginBtm5">营业执照识别</button>
</ocr-navigator>
<ocr-navigator bind:onSuccess="QCRPlatenumSuccess" certificateType="platenum">
<button type="primary" class="marginBtm5">车牌识别</button>
</ocr-navigator>
<ocr-navigator bind:onSuccess="QCRMenuSuccess" certificateType="menu">
<button type="primary" class="marginBtm5">菜单</button>
</ocr-navigator>
<!-- <ocr-navigator bind:onSuccess="QCRPrintedFontSuccess" certificateType="print">
<button type="primary">通用印刷体QCR</button>
</ocr-navigator> -->
</view>
<view class="margin-top">
<view class="content-title">
注意:
</view>
<view class="font-14-thin">
识别完图片之后,可以通过该插件回调返回的img_path的路径作为上传路径传给后台
</view>
</view>
</view>
</headTitle>
cardIdentify.json 文件
{
"usingComponents": {
"ocr-navigator": "plugin://ocr-plugin/ocr-navigator"
},
"navigationBarTitleText": "证件识别"
}
cardIdentify.js 文件
/* ***************** 小程序QCR插件证件识别 ******************* */
// 身份证识别--正面调用成功
QCRFontIdCard(ele) {
console.log('身份证识别调用成功', ele.detail)
const idCard = ele.detail
const address = idCard.address.text
const birth = idCard.birth.text
const gender = idCard.gender.text
const source = idCard.image_source
const idNumer = idCard.id.text
const name = idCard.name.text
const nationality = idCard.nationality.text
const image_path = idCard.image_path
const info = `姓名:${name};\n性别:${gender};\n民族:${nationality};\n出生日期:${birth};\n住址:${address};\n身份证号码:${idNumer};\n识别来源:${source}`
wx.showModal({
title: '身份证正面识别信息',
content: info,
success(res) {
if (res.confirm) {
console.log('用户确认信息无误,调用上传图片接口')
// app.commonModel.apis.upLoadImg(image_path).then(resData => {
// console.log('上传识别的图片',resData)
// })
}
}
})
},
// 身份证识别--背面调用成功
QCRBackIdCard(ele) {
console.log('身份证背面识别调用成功', ele.detail)
const backInfo = ele.detail
const authority = backInfo.authority.text
const validDate = backInfo.valid_date.text
const source = backInfo.image_source
const backInfoStr = `签发机关:${authority};\n有效期限:${validDate};\n识别来源:${source}`
wx.showModal({
title: '身份证背面识别信息',
content: backInfoStr,
success(res) {
if (res.confirm) {
console.log('用户确认信息无误,调用上传图片接口')
// app.commonModel.apis.upLoadImg(image_path).then(resData => {
// console.log('上传识别的图片',resData)
// })
}
}
})
},
// 银行卡识别
QCRBanksuccess(ele) {
console.log('银行卡号识别', ele.detail)
const bankInfo = ele.detail
const bankNumber = bankInfo.number.text
const source = bankInfo.image_source
const bankStr = `银行卡号:${bankNumber};\n识别来源:${source}`
wx.showModal({
title: '银行卡号识别信息',
content: bankStr,
success(res) {
if (res.confirm) {
console.log('用户确认信息无误,调用上传图片接口')
// app.commonModel.apis.upLoadImg(image_path).then(resData => {
// console.log('上传识别的图片',resData)
// })
}
}
})
},
// 行驶证识别
QCRDriverSuccess(ele) {
console.log('行驶证识别', ele.detail)
const driverInfo = ele.detail
const source = driverInfo.image_source
const image_path = driverInfo.image_path
const addr = driverInfo.addr.text
const check_record = driverInfo.check_record.text
const engine_num = driverInfo.engine_num.text
const issue_date = driverInfo.issue_date.text
const load_quality = driverInfo.load_quality.text
const model = driverInfo.model.text
const official_seal = driverInfo.official_seal.text
const overall_size = driverInfo.overall_size.text
const owner = driverInfo.owner.text
const passengers_num = driverInfo.passengers_num.text
const plate_num = driverInfo.plate_num.text
const plate_num_b = driverInfo.plate_num_b.text
const prepare_quality = driverInfo.prepare_quality.text
const record = driverInfo.record.text
const register_date = driverInfo.register_date.text
const remarks = driverInfo.remarks.text
const total_quality = driverInfo.total_quality.text
const use_character = driverInfo.use_character.text
const vehicle_type = driverInfo.vehicle_type.text
const vin = driverInfo.vin.text
const driverInfoStr = `正面:\n号牌号码:${plate_num};车辆类型:${vehicle_type};所有人:${owner};住址:${addr};使用性质:${use_character};品牌型号:${model};车辆识别代号:${vin};发动机号码:${engine_num};注册日期:${register_date};发证日期:${issue_date};发证部门:${official_seal};`
const backDriverInfo = `反面:\n号牌号码:${plate_num_b};档案编号:${record};核定载人数:${passengers_num};总质量:${total_quality};整备质量:${prepare_quality};核定载质量:${load_quality};外廓尺寸:${overall_size};准牵引总质量: ;备注:${remarks};检验有效期:${check_record};`
// const bankStr = `银行卡号:${bankNumber};\n识别来源:${source}`
wx.showModal({
title: '行驶证别信息',
content: driverInfoStr + backDriverInfo
})
},
// 驾驶证识别
QCRDriverLicenseSuccess(ele) {
console.log('驾驶证识别', ele.detail)
const driverInfo = ele.detail
const source = driverInfo.image_source
const image_path = driverInfo.image_path
const address = driverInfo.address.text
const birth_date = driverInfo.birth_date.text
const car_class = driverInfo.car_class.text
const file_no = driverInfo.file_no.text
const id_num = driverInfo.id_num.text
const issue_date = driverInfo.issue_date.text
const name = driverInfo.name.text
const nationality = driverInfo.nationality.text
const official_seal = driverInfo.official_seal.text
const remarks = driverInfo.remarks.text
const sex = driverInfo.sex.text
const valid_from = driverInfo.valid_from.text
const valid_to = driverInfo.valid_to.text
const driverInfoStr = `正面:\n姓名:${name};性别:${sex};国籍:${nationality};住址:${address};出生日期:${birth_date};初次领证日期:${issue_date};准假车型:${car_class};有效期限:${valid_from}至${valid_to};发证部门:${official_seal};\n反面:\n档案编号:${file_no};证号:${id_num};备注:${remarks};`
wx.showModal({
title: '驾驶证识别信息',
content: driverInfoStr
})
},
// 营业执照识别
QCRBusinessSuccess(ele) {
console.log('营业执照识别', ele)
},
// 车牌识别
QCRPlatenumSuccess(ele) {
console.log('车牌识别', ele)
const carNo = ele.number.text
console.log('识别的车牌号为', carNo)
},
// 菜单识别
QCRMenuSuccess(ele) {
console.log('菜单识别', ele)
const menuItem = ele.detail
console.log('菜单识别内容', menuItem)
const { image_path , image_source , items } = menuItem
let str = ''
if(items.length){
str = items.map(ele=>`${ele.menu_name}:${ele.menu_price}${ele.menu_memo}`).join('\n')
wx.showModal({
title: '菜单识别信息',
content: str
})
}else{
wx.showToast({
title: '无菜单信息',
icon:'none'
})
}
},
// 通用印刷体QCR
QCRPrintedFontSuccess(ele) {
console.log('通用印刷体QCR', ele)
},
/* ***************** 小程序QCR插件证件识别 ******************* */