微信小程序实现OCR扫描识别 Posted 2023-04-11 三个木马人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序实现OCR扫描识别相关的知识,希望对你有一定的参考价值。
在小程序还发过程中,经常会遇到对证件(身份证、驾驶证、营业执照)的扫描识别认证功能;这里我根据自己的经历借鉴总结一下相关的方法;
文章目录
一、第三方插件: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"
页面使用
< 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>
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) ;
)
) ;
)
,
getBase64Path ( path)
return new Prmise ( ( resolve, reject) = >
wx. getFileSystemManager ( ) . readFile (
filePath: path,
encoding: 'base64' ,
success: function ( res)
resolve ( res. data) ;
,
)
)
调用身份证OCR识别之前需要先获取 access_token
getToken ( )
return new Promise ( ( resolve, reject) = >
let appKey = 'xxxxx' ;
let secretKey = 'xxxxx' ;
let url = `https:
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:
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 ,
y: 200 ,
width: imgWidth,
height: imgHeight,
destWidth: imgWidth,
destHeight: imgHeight,
success ( res)
that. setData (
image: res. tempFilePath,
showPic: true
)
)
) , 1000 )
)
,
)
这里的重点是对截图框位置的计算,可以根据自己的需求来设计宽高;
4、由于 createCanvasContext 在 2.9.0 开始停止维护,官网推荐使用 Canvas 代替
< 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>
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
ctx. drawImage ( img, c_x, c_y, c_w, c_h, 0 , 0 , 300 , 300 * ( c_h / c_w) )
wx. canvasToTempFilePath (
canvas: canvas,
width: 335 ,
height: 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方法参数详解
微信小程序接入百度OCR(身份证识别)
微信小程序接入百度OCR(身份证识别)
1.接口描述
支持对二代居民身份证正反面所有8个字段进行结构化识别,包括姓名、性别、民族、出生日期、住址、身份证号、签发机关、有效期限,识别准确率超过99%;同时支持身份证正面头像检测,并返回头像切片的base64编码及位置信息。
同时,支持对用户上传的身份证图片进行图像风险和质量检测,可识别图片是否为复印件或临时身份证,是否被翻拍或编辑,是否存在正反颠倒、模糊、欠曝、过曝等质量问题。
请求示例
HTTP 方法:POST
请求URL: https://aip.baidubce.com/rest/2.0/ocr/v1/idcard
URL参数:
参数
值
access_token
通过API Key和Secret Key获取的access_token,参考“Access Token获取 ”
Header如下:
参数
值
Content-Type
application/x-www-form-urlencoded
Body中放置请求参数,参数详情如下:
请求参数
参数
是否必选
类型
可选值范围
说明
image
是
string
-
图像数据,base64编码后进行urlencode,要求base64编码和urlencode后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/jpeg/png/bmp格式
id_card_side
是
string
front/back
front:身份证含照片的一面;back:身份证带国徽的一面
detect_direction
否
string
true/false
是否检测图像旋转角度,默认检测,即:true。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括: - true:检测旋转角度; - false:不检测旋转角度。
detect_risk
否
string
true/false
是否开启身份证风险类型(身份证复印件、临时身份证、身份证翻拍、修改过的身份证)功能,默认不开启,即:false。可选值:true-开启;false-不开启
detect_photo
否
string
true/false
是否检测头像内容,默认不检测。可选值:true-检测头像并返回头像的 base64 编码及位置信息
detect_rectify
否
string
true/false
是否进行完整性校验,默认为true,需上传各字段内容完善的图片方可识别;如果设置为false,则对于身份证切片(如仅身份证号区域)也可识别
2.小程序端调用
需要参数access_token,存放在云数据库中,并定时刷新,不明白如何获取并定时刷新的参考文章:
[小程序开发技巧总结(三)-- 云开发时效数据刷新和存储 (access_token等) ]
tips:核心部分是在本地完成base64 编码
2.1 自定义文件 profunc.js ,实现函数并封装
function OcrIdCard(access_token){
return new Promise(function(resolve,reject){
var that = this;
//识别身份证
wx.chooseImage({
count: 1,
sizeType: [\'compressed\'],
sourceType: [\'album\', \'camera\'],
success: function (res) {
console.log(res.tempFilePaths)
//核心代码
wx.getFileSystemManager().readFile({
filePath: res.tempFilePaths[0],
encoding: \'base64\', //编码格式
success(ans) {
// console.log(ans.data)
wx.showLoading({ title: \'识别中\' })
wx.request({
url: \'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=\' + access_token,
method: \'POST\',
header: {
\'Content-Type\': \'application/x-www-form-urlencoded\'
},
data: {
image: ans.data,
id_card_side: \'front\'
},
success(_res) {
wx.hideLoading();
resolve(_res)
}, fail(_res) {
wx.hideLoading();
wx.showToast({
title: \'请求出错\',
})
reject(_res)
}
})
}
})
}
})
})
}
module.exports = {
OcrIdCard: OcrIdCard
}
2.2 在小程序页面引用,需要传入access_token
const cwx = require(\'profunc.js\'); //在小程序页面引入该js 文件
...
ocridcard(){
var that = this;
cwx.OcrIdCard(that.data.access_token).then(function(_res){
var trdata = _res.data.words_result;
console.log(trdata)
that.setData({
name: trdata[\'姓名\'].words,
idcard: trdata[\'公民身份号码\'].words,
userloc: trdata[\'住址\'].words
})
})
}
3.效果展示
接口返回数据如下
小程序 Android Web 等开发欢迎联系 QQ 1025584691
以上是关于微信小程序实现OCR扫描识别的主要内容,如果未能解决你的问题,请参考以下文章
微信小程序实现身份证识别-ocr
微信小程序接入百度OCR(身份证识别)
微信小程序 腾讯云ocr 身份证识别
微信小程序识别二维码跳转到应用商店
微信小程序怎么将文字变成图片
微信小程序登陆不上去怎么回事?