最近在翻微信小程序文档的时候,意外看到了微信有ocr识别,细看发现一天可以免费使用100次,直接就用上先。
效果图:
具体的实现逻辑还是很简单的,微信小程序调用相机,然后选择拍照上传照片或者是从图库里选择照片上传到微信的ocr接口,然后接口识别后将结果返回给前端进行渲染或者其他操作。
1,页面显示解构
我这里是很常见的身份证识别结构,后续可以根据实际需求进行修改,注意先在data中定义号姓名和地址等这个几个参数。
<view>
<view>
<image src="{{imagrurl}}" mode="aspectFit" style="height:500rpx;width:100%" />
<button bind:tap="platenumSuccess" data-num='1'>身份证正面识别</button>
<view>姓名:{{name}}</view>
<view>地址:{{site}}</view>
<view>身份证号码:{{id}}</view>
</view>
<view>
<image src="{{imagrurlBack}}" mode="aspectFit" style="height:500rpx;width:100%" />
<button bind:tap="platenumSuccess" data-num='2'>身份证背面识别</button>
<view>所在地:{{authority}}</view>
<view>有效果期限:{{valid_date}}</view>
</view>
</view>
2,点击识别按钮后,打开相机,获取本地图片的微信地址
在页面的js文件中定义我们的data数据
data: {
imagrurl: "",
imagrurlBack: "",
name: "",
site: "",
authority: "",
valid_date: "",
pathres: ""
},
然后在定义我们的相机打开逻辑,将相机打开逻辑绑定在按钮上,当点击身份证正面或者反面时,打开摄像头。这里注意区分一下,因为有正面和反面,所有按钮要传不同的参数,来区分显示的时正面还是反面按钮。
platenumSuccess: function (e: any) {
wx.chooseMedia(
{
count: 1,
mediaType: "image",
camera: "back",
success: async (res: any) => {
if (e.currentTarget.dataset.num === '1') {
this.setData({
imagrurl: res.tempFiles[0].tempFilePath,
})
}
else {
this.setData({
imagrurlBack: res.tempFiles[0].tempFilePath,
})
}}})}
3.将图片上传到微信的ocr识别。
重新封装下上传,后续更好的使用,这里的res形参我们接收的是wx图片在本机的路径。
upload: (res: any) => {
return new Promise((resolve, reject) => {
wx.uploadFile({ //因为我传的是fromdata格式,所有直接用微信的uploadfile接口来传就好了
url: "https://api.weixin.qq.com/cv/ocr/idcard?access_token=83_ohBU0fLiJPjmQITB_bZfaqfkXV0eBwFbDh5W72dunadjoj4tNNU1P1utbQ7cc_xA2UYvNpkAdr7BgQAw5fSnzmoyTTTosr0F3kLhBZJBaU0BFS2YLlgMLTumbCkSXMeABAVAP",
filePath: res,
name: 'file',
success: (res: any) => {
var data = JSON.parse(res.data)
resolve(data)
}
})
})
},
4.将打开摄像头和上传的方法进行组合识别
platenumSuccess: function (e: any) {
wx.chooseMedia(
{
count: 1, //一张
mediaType: "image", //图片
camera: "back",//后置摄像头
success: async (res: any) => {
if (e.currentTarget.dataset.num === '1') {//当点击是正面时,将获取到的地址赋值给变量,然后这个变量给页面上的image标签渲染图片。
this.setData({
imagrurl: res.tempFiles[0].tempFilePath,
})
}
else {
this.setData({
imagrurlBack: res.tempFiles[0].tempFilePath,
})
}
let ocr = await this.upload(res.tempFiles[0].tempFilePath)
if (e.currentTarget.dataset.num === '1') {//这里是正面
this.setData({
name: ocr.name,
id: ocr.id,
site: ocr.addr
})
} else if (e.currentTarget.dataset.num === '2' && ocr.type == 'Back') { //判断是正面还是反面,反面的话接口会返回type参数,然后我们就渲染反面的内容。
this.setData({
valid_date: ocr.valid_date,
authority: ocr.authority
})
}
}
}
)
},
这样就实现了微信小程序的ocr识别功能
5,注意
1,微信小程序ocr识别接口access_token参数,微信官网给出了获取的地方,这里要注意下,一般来说 这个数据时后端开发人员获取的,微信前端获取是不安全的。
视频号小店API / 通用API / 获取AccessToken (qq.com)
2,我们提交的图片给微信识别的接口api.weixin.qq.com,是不允许在线上版本上直接在微信前端访问的,一般来说都是我们传图片给后端,后端在把图片给微信官网识别,在通过后端把数据返回给前端,这里因为我是测试一下,所以就之前在前端访问了。开启后就能在前端访问。
3. 我只是写着玩玩,业务逻辑肯定有漏洞的,比如图片尺寸校验,或者是图片传入的不是身份证校验,这个在官网文档上都有,花点时间看看就行,代码也是我随手写的,可能写的不是很好,多多见谅,毕竟是写着玩的,最后,所有代码在下面。
6.代码
index. wxml
<view>
<view>
<image src="{{imagrurl}}" mode="aspectFit" style="height:500rpx;width:100%" />
<button bind:tap="platenumSuccess" data-num='1'>身份证正面识别</button>
<view>姓名:{{name}}</view>
<view>地址:{{site}}</view>
<view>身份证号码:{{id}}</view>
</view>
<view>
<image src="{{imagrurlBack}}" mode="aspectFit" style="height:500rpx;width:100%" />
<button bind:tap="platenumSuccess" data-num='2'>身份证背面识别</button>
<view>所在地:{{authority}}</view>
<view>有效果期限:{{valid_date}}</view>
</view>
</view>
index.ts
Page({
data: {
imagrurl: "",
imagrurlBack: "",
name: "",
site: "",
authority: "",
valid_date: "",
pathres: ""
},
// 调用事件方法,上传图片到微信服务器/线上后不能直接在前端直接上传到微信服务器
upload: (res: any) => {
return new Promise((resolve, reject) => {
wx.uploadFile({
url: "https://api.weixin.qq.com/cv/ocr/idcard?access_token=83_ohBU0fLiJPjmQITB_bZfaqfkXV0eBwFbDh5W72dunadjoj4tNNU1P1utbQ7cc_xA2UYvNpkAdr7BgQAw5fSnzmoyTTTosr0F3kLhBZJBaU0BFS2YLlgMLTumbCkSXMeABAVAP",
filePath: res,
name: 'file',
success: (res: any) => {
var data = JSON.parse(res.data)
resolve(data)
}
})
})
},
platenumSuccess: function (e: any) {
wx.chooseMedia(
{
count: 1,
mediaType: "image",
camera: "back",
success: async (res: any) => {
if (e.currentTarget.dataset.num === '1') {
this.setData({
imagrurl: res.tempFiles[0].tempFilePath,
})
}
else {
this.setData({
imagrurlBack: res.tempFiles[0].tempFilePath,
})
}
let ocr = await this.upload(res.tempFiles[0].tempFilePath)
if (e.currentTarget.dataset.num === '1') {
this.setData({
name: ocr.name,
id: ocr.id,
site: ocr.addr
})
} else if (e.currentTarget.dataset.num === '2' && ocr.type == 'Back') {
this.setData({
valid_date: ocr.valid_date,
authority: ocr.authority
})
}
}
}
)
},
})
拜拜ヾ(•ω•`)o