当前位置:网站首页>微信小程序实现OCR扫描识别
微信小程序实现OCR扫描识别
2022-06-10 23:21:00 【三个木马人】
在小程序还发过程中,经常会遇到对证件(身份证、驾驶证、营业执照)的扫描识别认证功能;这里我根据自己的经历借鉴总结一下相关的方法;
文章目录
一、第三方插件:OCR支持
1、添加第三方插件
第一步需要在微信小程序后台添加第三方插件,设置-第三方设置-插件管理,输入**ocr支持**搜索添加就可以了;
2、购买识别次数
OCR支持插件添加成功之后需要到开放社区购买识别次数,可以根据自己公司的业务需求量购买;(个人觉得有点贵)
3、使用
在 app.json 中声明引入插件,version 使用最新版本,provider 是OCR支持的 AppID;
"plugins": {
"ocr-plugin": {
"version": "3.1.1",
"provider": "wx4418e3e031e551be"
}
}
在使用OCR支持的页面 json 中引入组件
{
"usingComponents": {
"ocr-navigator": "plugin://ocr-plugin/ocr-navigator"
}
}
页面使用
//wxml
<ocr-navigator bind:onSuccess="success" certificateType="idCard" opposite="{
{false}}">
<button type="primary">身份证正面识别</button>
</ocr-navigator>
<ocr-navigator bind:onSuccess="success" certificateType="idCard" opposite="{
{true}}">
<button type="primary">身份证反面识别</button>
</ocr-navigator>
//js
Page({
data:{
name:'',
id:''
},
success(e){
console.log(e.detail)
this.setData({
name:e.detail.name.text,
id:e.detail.id.text
})
}
})

注意:certificateType 类型不同属性也不同可以参考:OCR支持开发文档
二、百度OCR
1、申请百度AI开放平台账号
申请地址:http://ai.baidu.com/?track=cp:aipinzhuan|pf:pc|pp:AIpingtai|pu:title|ci:|kw:10005792
2、创建应用获取密钥
开放能力-文字识别 ,这里有身份证、银行卡、营业执照、护照、出生证明等识别服务;

按照个人需要填写信息,创建应用之后,在应用列表可以查看对应的 API Key 、Secret Key、AppID 等信息;
3、使用
1、配置合法域名
在使用之前,我们需要将百度OCR接口域名配置在微信小程序后台的合法域名中(https://aip.baidubce.com);
2、接口分析(身份证)
接口、入参参考:技术文档
3、调用
获取身份证图片
// 点击扫证,可拍照、可选择本机图片
getImage(){
let that = this
wx.showActionSheet({
itemList: ['拍照','相册'],
success(res){
let index = res.tabIndex;
if(index == 0){
that.gotophoto();
}else{
that.getAlbum();
}
}
})
},
//从相册选择图片
getAlbum(){
let that = this;
wx.chooseImage({
count: 1,
sourceType: ['album'],
success:function(res){
let path = res.tempFilePaths[0];
that.getBase64Path(path).then(base64=>{
that.ocrCard(base64).then(res=>{
//这里就是扫描的结果
console.log(res);
})
});
}
})
},
//本地转化为base64编码
getBase64Path(path){
return new Prmise((resolve,reject)=>{
wx.getFileSystemManager().readFile({
filePath: path,
encoding: 'base64',
success: function (res) {
resolve(res.data);
},
})
})
}
调用身份证OCR识别之前需要先获取 access_token
//获取access_token
getToken(){
return new Promise((resolve,reject)=>{
let appKey = 'xxxxx';
let secretKey = 'xxxxx';
let url = `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${appKey}&client_secret=${secretKey}`;
wx.request({
url: url,
method:'POST',
dataType:'json',
header:{
'content-type': 'application/json; charset-UTF-8'
},
success(res){
resolve(res);
},
fail(err){
reject(err);
}
})
})
},
识别身份证
//识别图片
ocrCard(data){
return new Promise((resolve,reject)=>{
this.getToken().then(res=>{
let token = res.data.access_token
let url = `https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=${token}`;
wx.request({
url: url,
method:'POST',
header:{
'Content-Type': 'application/x-www-form-urlencoded'
},
data:{
image:data,
id_card_side:'front'
},
success(res){
resolve(res);
},
fail(err){
reject(err);
}
})
})
})
}
上面就是照片选择到身份证OCR识别的整个过程;关于 access_token 也可以在页面加载的时候获取一次,然后将 access_token 缓存在本地,这样每次获取的时候需要先判断 access_token 是否过期;
三、拍照、照片裁剪
对于拍照的照片,有些时候我们可能需要对其进行裁剪;
1、跳转到拍照页面
gotophoto(){
wx.navigateTo({
url: '/pages/photo/photo'
})
}
2、拍照页面
<camera type="2d" device-position="back" resolution="high" style="width: 100%; height: 100vh;">
<cover-view>
<!-- 拍照后的回显图片,必须在裁剪蒙层上面,不然不显示 -->
<cover-image wx:if="{
{showPic}}" src="{
{image}}"></cover-image>
<!-- 拍照蒙层,按照这个裁剪 -->
<cover-image src="http://print.jiaynet.cn/icons/zhezhao.png"></cover-image>
</cover-view>
<!-- 拍照按钮 -->
<cover-view style="color: #fff; width: 100%; position: fixed; left:0; bottom: 40rpx;">
<cover-view bindtap="takePhotoAction" style="width: 100%; text-align: center;">拍照</cover-view>
</cover-view>
</camera>
<!-- 这里的宽高一定不要忘记设置 -->
<canvas style='width:{
{
width}}px; height:{
{
height}}px; opacity: 0;' canvas-id="mycanvas"></canvas>
3、拍照
data: {
width:0,//设备宽度
height:0,//设备高度
image:'',
showPic:false
},
takePhotoAction(){
let that = this;
let ctx = wx.createCameraContext();
ctx.takePhoto({
quality:'high',
success(res){
that.loadTempImagePath(res.tempImagePath)
}
})
},
//剪切图片
loadTempImagePath(path){
let that = this;
//获取设备宽高信息
wx.getSystemInfo({
success: (res) => {
that.setData({
width:res.screenWidth,
height:res.screenHeight
})
let imgX = 0.1*that.data.width;
let imgY = 0.25*that.data.height;
let imgWidth = 0.8*that.data.width;
let imgHeight = 0.25*that.data.height;
//获取图片信息
wx.getImageInfo({
src: path,
success(res){
const canvas = wx.createCanvasContext('mycanvas', that);
//将图片放到画布上
canvas.drawImage(path,0,0,that.data.width,that.data.height);
//截取图片
canvas.draw(false,setTimeout(()=>{
wx.canvasToTempFilePath({
canvasId: 'mycanvas',
x: 50, //画布x轴起点
y: 200, //画布y轴起点
width: imgWidth, //画布宽度
height: imgHeight, //画布高度
destWidth: imgWidth, //输出图片宽度
destHeight: imgHeight, //输出图片高度
success(res){
that.setData({
image:res.tempFilePath,
showPic:true
})
}
})
}),1000)
}
})
},
})
}
这里的重点是对截图框位置的计算,可以根据自己的需求来设计宽高;
4、由于 createCanvasContext 在 2.9.0 开始停止维护,官网推荐使用 Canvas 代替
//wxml
<camera type="2d" device-position="back" resolution="high" style="width: 100%; height: 100vh;">
<cover-view>
<!-- 拍照后的回显图片,必须在上面,不然不显示 -->
<cover-image style="position: absolute; top: 0; left: 0; width: 348px; height: auto;" wx:if="{
{showPic}}" src="{
{image}}"></cover-image>
<!-- 拍照蒙层,按照这个裁剪 -->
<cover-image src="http://print.jiaynet.cn/icons/zhezhao.png"></cover-image>
</cover-view>
<!-- 拍照按钮 -->
<cover-view style="color: #fff; width: 100%; position: fixed; left:0; bottom: 40rpx;">
<cover-view bindtap="takePhotoAction" style="width: 100%; text-align: center;">拍照</cover-view>
</cover-view>
</camera>
<!-- -->
<canvas type="2d" id="mycanvas"></canvas>
//js
takePhotoAction(){
let that = this;
let ctx = wx.createCameraContext();
ctx.takePhoto({
quality:'high',
success(res){
that.setData({
image:res.tempImagePath
})
wx.createSelectorQuery()
.select('#mycanvas')
.fields({
node: true,
size: true
}, (res) => {
const canvas = res.node
const ctx2 = canvas.getContext('2d');
that.init(ctx2, canvas)
})
.exec()
}
})
},
init(ctx, canvas) {
let img = canvas.createImage()
img.src = this.data.image;
img.onload = (e) => {
let c_x = img.width * 0.05
let c_w = img.width * 0.89
let c_y = img.height * 0.365
let c_h = img.height * 0.12
//截取图片指定部分并绘制到canvas
ctx.drawImage(img, c_x, c_y, c_w, c_h, 0, 0, 300, 300 * (c_h / c_w))//width固定为300,按比例计算出height
//将canvas内容保存为图片
wx.canvasToTempFilePath({
canvas: canvas,
// x: 50, //画布x轴起点
// y: 280, //画布y轴起点
width: 335, //画布宽度
height: 216, //画布高度
// destWidth: 335, //输出图片宽度
// destHeight: 216, //输出图片高度
fileType: 'png',
success: (res) => {
this.setData({
image:res.tempFilePath,
showPic:true
})
//将图片保存到本地相册
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
})
},
fail: (res) => {
console.log(res)
}
})
}
img.onerror = (e) => {
console.error('err:', e)
}
}
由于使用 canvas 时的 drawImage 参数比较难理解,请参考:canvas的drawImage方法参数详解
边栏推荐
猜你喜欢

763. dividing alphabetic intervals

String time sorting, sorting time format strings

From the perspective of Confucius Temple IP crossover, we can see how the six walnuts become "butterflies" for the second time

【无标题】6666666

Review of software architecture in Harbin Institute of technology -- LSP principle, covariance and inversion

第一章 总论-会计基础

763. 划分字母区间

Bluetooth development (3) -- look at the air bag

Bluetooth development (8) -- avdtp connection process

VTK例子--三個相交的平面
随机推荐
sql 语句--输入 月份 查日期(年月日),输出 月份
Website online customer service system Gofly source code development log - 5 Gin framework integration daemon
333333
12324243242
BGP基础概念及IBGP基本配置
Typecho blog site wide deployment of Tencent cloud CDN tutorial - Xingze V Club
[untitled] test
Docking request mode
Multipass中文文档-概览
How to check the variable waveform when debugging the program? Look here
Things about Bluetooth development (10) -- getting to know ble for the first time
Bluetooth development (8) -- avdtp connection process
USB IP core FPGA debugging (I)
Is it safe to open an account for stock speculation in Shanghai?
canvas绘画折线段
Learning notes: hook point of plug-in activity
phpstudy的安装
市值215亿,这个四川80后会让电视机成为历史?
teterttet
【无标题】4555