为了减轻采集身份证信息时频繁输入的负担,有必要开发出直接获取身份证信息的功能,打开小程序开发指南,搜索发现恰好有相关API提供
整个操作可分为三步走,首先用相机对身份证拍照或者选择手机上已拍好的身份证照片,然后把身份证照片上传到微信小程序服务器,当然如果有自己的服务器最好上传到自己的服务器,最后调用ocr识别模块进行信息识别

一、拍照
核心方法:wx.chooseImage(Object object)
<view bindtap = "chooseImg"><text>选择照片</text></view>
chooseImg: function () {
var self = this
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
// tempFilePath可以作为img标签的src属性显示图片,回调结果
const tempFilePaths = res.tempFilePaths
// ["http://tmp/f3zhptK14bYufe32ad6da213512bffb42e2069144d58.png"]
console.log(tempFilePaths )
// 后续操作见第二步操作【上传】
}
})
},
二、上传
核心方法1:wx.cloud.uploadFile
PS:UploadTask wx.uploadFile(Object object)
如果开发者有自己的服务器的话,可以使用此方法将图片上传到开发者服务器以保证数据安全和维护方便
为了生成一个唯一的文件名,需要用到uuid,而uuid是在utils中的一个工具类方法
const wxuuid = function () {
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid
}
module.exports = {
wxuuid: wxuuid
}
也可以直接截取文件名
const name = tempFilePaths[0].substr(tempFilePaths[0].indexOf('tmp') + 4,tempFilePaths[0].length)
建议还是使用uuid方式
var util = require('../../utils/util.js');
此处代码接第一步操作
// 由于count等于1,所以此处的tempFilePaths数组长度只有1
const suffix = tempFilePaths[0].substr(tempFilePaths[0].lastIndexOf('.'),tempFilePaths[0].length)
// 得到选择图片的后缀名后,加上uuid则组成了待上传的文件名
const newName = util.wxuuid() + suffix
wx.cloud.uploadFile({
cloudPath: newName ,
filePath: tempFilePaths[0], // 文件路径
success: res => {
// get resource ID
console.log(res.fileID)
// 此处要得到图片的url,就需要用fileID去换
this.getUrlById(res.fileID)
},
fail: err => {
// handle error
console.log(err)
}
})
核心方法2:Cloud.getTempFileURL(fileList: string[]): Promise
getUrlById:function(resId){
var self = this
wx.cloud.getTempFileURL({
fileList: [{
fileID: resId,
maxAge: 60 * 60, // one hour
}]
}).then(res => {
// get temp file URL
console.log(res.fileList[0].tempFileURL)
// 后续操作见第三步操作【识别】
this.getSfz(res.fileList[0].tempFileURL)
}).catch(error => {
// handle error
})
},
三、识别
核心方法:ocr.idcard
微信小程序ocr可识别银行卡、身份证、驾驶证、行驶证、营业执照等,本文仅以身份证识别为例。
注意:使用说明中明确表明免费额度100次/天,但是普通个人开发者想要使用免费额度的话也得走服务市场购买免费额度才能正常使用,否则会报如下错误
{
"errMsg":"cloud.callFunction:ok",
"result":{
"errCode":101003,
"errMsg":"openapi.ocr.idcard:fail not enough market quota hint: [R0ZEGa03053705] rid: 60349ef9-77517716-18d8122a"
},
"requestID":"66fc3287-759f-11eb-8a74-525400a255c0"
}
购买时需要指定一个小程序
购买成功后,免费额度方可正常使用
如果使用开发文档中默认的值imgUrl: ‘ENCODE_URL’,则会报如下错误
{
"errMsg":"cloud.callFunction:ok",
"result":{
"errCode":101000,
"errMsg":"openapi.ocr.idcard:fail invalid image url hint: [5Fd9Va07430396] rid: 6034a0af-3674090a-33369c90"
},
"requestID":"6bfc6c3c-75a0-11eb-aa81-525400b84760"
}
此时我们把图片url改成一个百度的图片地址,不带身份证信息的,比如这张https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1742408536,1078898080&fm=26&gp=0.jpg,那么就会报如下错误
{
"errMsg":"cloud.callFunction:ok",
"result":{
"errCode":101001,
"errMsg":"openapi.ocr.idcard:fail certificate not found hint: [b5J7va09763705] rid: 6034a198-149dec4a-0d4ad930"
},
"requestID":"f7226d85-75a0-11eb-b8fc-5254001c5def"
}
最后只要我们把图片url换成有身份证信息的地址,那么就能识别成功
此处代码接第二步操作
getSfz: function (url) {
wx.cloud.init({
traceUser: true
})
wx.cloud.callFunction({
name: 'getOcrSfz',
data: {
imgUrl: url, // 传给云函数的参数
},
complete: res => {
console.log('getSfz=' + JSON.stringify(res))
}
})
},
此处是调用的云函数getOcrSfz,云函数记得执行【上传并部署:云端安装依赖】操作
config.json
{
"permissions": {
"openapi": [
"ocr.idcard"
]
}
}
index.js
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
try {
let imgUrl = event.imgUrl;
const result = await cloud.openapi.ocr.idcard({
type: 'photo',
imgUrl: imgUrl
})
return result
} catch (err) {
return err
}
}
四、实际演示
我们在网上找了一张测试用的身份证照片,通过选择照片-上传照片-识别照片三步走之后得到的信息如下
{
"errMsg":"cloud.callFunction:ok",
"result":{
"type":"Front",
"name":"奥巴马",
"id":"123456196108047890",
"addr":"华盛顿特区宜宾法尼亚大道1600号白宫",
"gender":"男",
"nationality":"青尼汉",
"birth":"1961-8-4",
"cardProperty":1,
"errMsg":"openapi.ocr.idcard:ok",
"errCode":0
},
"requestID":"02180070-7644-11eb-ae53-525400fbcc42"
}
从以上信息可以看到,除了民族识别错误,其他都是正确的,根据本人亲测,只要使用有效的身份证照片来识别的话,那么识别的结果都是正确无误的