uni-app之接入百度OCR识别身份证(微信小程序版本)

本文为uni-app接入百度OCR识别身份证号,话不多说,直接上代码:

1. 第一步注册百度智能云账号,选择文字识别,创建应用,获取Api Key 与 Secret Key(下面要用到):

2.第二步,查看百度OCR身份证识别技术文档,如下,共需调用2个接口:

第一接口:获取百度access_token, 上代码:

getBDtoken() {
      uni.showLoading({
        title: '正在连接服务...'
      })
      return new Promise(resolve => {
        uni.request({
          url: 'https://aip.baidubce.com/oauth/2.0/token', // 百度获取token接口地址
          data: {
            'grant_type': 'client_credentials', // 固定写死
            'client_id': '你上面申请获取的API Key',
            'client_secret': '你上面申请的Secret Key'
          },
          method: 'GET',
          success(res) {
            resolve(res)
          },
          fail(e) {
            uni.hideLoading()
            Modal.toast('连接服务出错,请稍后再试!')
          }
        })
      })
    }

第二个接口先不要着急,请继续往下看:

3.百度OCR的第二个接口入参需要图像信息,这个图像信息怎么获取呢?上代码:

takePhoto() {
      // 直接调用uni-app现有API, 爽翻天
      const ctx = uni.createCameraContext()
      ctx.takePhoto({
        quality: 'high',
        success: async res => {
            let path = res.tempImagePath // 拍照的临时地址
            // 这里用百度ORC身份识别的image参数,需要转成base64格式
            let base64String = `${wx.getFileSystemManager().readFileSync(path, "base64")}`
        },
        fail: err => {
          uni.hideLoading()
          Modal.toast('生成图片错误, 请稍后重试!')
        }
      })
    },

4.好了,到这里就可以调用百度OCR的第二个接口了,上代码:

// 参数准备
// const params = {
//   access_token: data.data.access_token,
//   data: {
//     image: base64String,
//     id_card_side: 'front'
//   }
// }


// 这个接口才是真正的识别身份证,上面准备的access_token,base64String都为此准备
getIdCard(params) {
      uni.showLoading({
        title: '正在解析...'
      })
      return new Promise(resolve => {
        uni.request({
          // 身份证识别接口
          url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=' + params.access_token,
          data: params.data,
          method: 'POST',
          header: {
            "Content-Type": "application/x-www-form-urlencoded"
          },
          success(res) {
            uni.hideLoading()
            resolve(res)
          },
          fail(e) {
            uni.hideLoading()
            Modal.toast('解析出错,请稍后再试!')
          },
          complete() {
          }
        })
      })
    },

5.效果图:

6.完整代码,可以直接拿去用,不喜欢样式的自行修改:

<template>
  <view class="container">
    <camera device-position="back" flash="auto" @error="error" class="camera">
      <cover-view class="cover-view">
        <cover-view class="cover-view-top"></cover-view>
        <cover-view class="scan-img-view">
          <cover-image src="../../static/img/idCard/scan-img.png" class="scan-img" id="scanImg"></cover-image>
          <cover-view class="tips">
            <cover-view>{{tips}}</cover-view>
          </cover-view>
        </cover-view>
        <cover-view class="cover-view-bot">
          <cover-image src="../../static/img/idCard/takePhoto.png" class="take-img" @click="takePhoto"></cover-image>
        </cover-view>
        <cover-view class="id-card-info" v-if="dialogVisible">
          <cover-view class="middle">
            <cover-view class="title">识别结果</cover-view>
            <cover-view class="content">
              <cover-view class="item">
                <cover-view class="label">姓名: </cover-view>
                <cover-view class="value">{{cradInfo.name}}</cover-view>
              </cover-view>
              <cover-view class="item">
                <cover-view class="label">出生日期: </cover-view>
                <cover-view class="value">{{cradInfo.birthdate}}</cover-view>
              </cover-view>
              <view class="item">
                <cover-view class="label">性别: </cover-view>
                <cover-view class="value">{{cradInfo.sex === '801' ? '男':'女'}}</cover-view>
              </view>
              <view class="item">
                <cover-view class="label">身份证号: </cover-view>
                <cover-view class="value">{{cradInfo.idNo}}</cover-view>
              </view>
            </cover-view>
            <cover-view class="footer">
              <cover-view class="btn sure">确认信息</cover-view>
              <cover-view class="btn cancel" @click="closeDialog">重新识别</cover-view>
            </cover-view>
          </cover-view>
        </cover-view>
      </cover-view>
    </camera>
  </view>
</template>

<script>
let t
export default {
  data() {
    return {
      cradInfo: {},
      dialogVisible: false,
      tips: '请将身份证置于拍照区域拍照'
    }
  },
  onShow() {
    const timer = setTimeout(() => {
      this.setTipsStatus()
      clearTimeout(timer)
    }, 1000)
  },
  methods: {
    setTipsStatus() {
      let num = 0
      t = setInterval(() => {
        num++
        if (num > 4) {
          num = 0
        }
        this.tips = '请将身份证置于拍照区域拍照' + '....'.substring(0, num)
      }, 1000)
    },
    takePhoto() {
      const ctx = uni.createCameraContext()
      ctx.takePhoto({
        quality: 'high',
        success: async res => {
          this.drawCanvas(res.tempImagePath)
        },
        fail: err => {
          uni.hideLoading()
          uni.showToast({
            title: '生成图片错误, 请稍后重试!'
          })
        }
      })
    },
    drawCanvas(path) {
      uni.showLoading({
        title: '正在生成图片...'
      })
      let base64String = `${wx.getFileSystemManager().readFileSync(path, "base64")}`
      this.getBDtoken().then(data => {
        const params = {
          access_token: data.data.access_token,
          data: {
            image: base64String,
            id_card_side: 'front'
          }
        }
        this.getIdCard(params).then(res => {
          if (res) {
            const result = res.data.words_result
            this.cradInfo = {
              idNo: result['公民身份号码'] ? result['公民身份号码'].words : '',
              name: result['姓名'] ? result['姓名'].words : '',
              sex: result['性别'] ? (result['性别'].words === '男' ? '801' : '802') : '801',
              birthdate: result['出生'] ? (result['出生'].words.substring(0, 4) + '-' + result['出生'].words.substring(4, 6) + '-' + result['出生'].words.substring(6, 8)) : '',
            }
            this.dialogVisible = true
          }
        })
      })
    },
    getBDtoken() {
      uni.showLoading({
        title: '正在连接服务...'
      })
      return new Promise(resolve => {
        uni.request({
          url: 'https://aip.baidubce.com/oauth/2.0/token',
          data: {
            'grant_type': 'client_credentials',
            'client_id': '你申请的API Key',
            'client_secret': '你申请的Secret Key'
          },
          method: 'GET',
          success(res) {
            resolve(res)
          },
          fail(e) {
            uni.hideLoading()
            uni.showToast({
                title: '连接服务出错,请稍后再试!'
            })
          }
        })
      })
    },
    getIdCard(params) {
      uni.showLoading({
        title: '正在解析...'
      })
      return new Promise(resolve => {
        uni.request({
          url: 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=' + params.access_token,
          data: params.data,
          method: 'POST',
          header: {
            "Content-Type": "application/x-www-form-urlencoded"
          },
          success(res) {
            uni.hideLoading()
            resolve(res)
          },
          fail(e) {
            uni.hideLoading()
            uni.showToast({
                title: '解析出错,请稍后再试!'
            })
          },
          complete() {
          }
        })
      })
    },
    error(e) {
      console.log(e.detail);
    },
    closeDialog() {
      this.dialogVisible = false
      this.cradInfo = {}
    }
  }
}
</script>

<style lang="scss" scoped>

.container{
  position: relative;
}

.camera {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 99;
  width: 750upx;
  height: 100%;
}

.cover-view {
  width: 750upx;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.cover-view-top {
  width: 750upx;
  height: 200upx;
  background-color: rgba(0, 0, 0, .4);
}

.cover-view-bot {
  flex: 1;
  width: 750upx;
  background-color: rgba(0, 0, 0, .4);
  display: flex;
  justify-content: center;
  align-items: center;

  .take-img {
    width: 120upx;
    height: 120upx;
  }
}

.canvas{
  position: absolute;
  top: 240upx;
  left: 45upx;
  height: 410upx;
  width: 660upx;
}

.scan-img-view{
  position: relative;
  .scan-img {
    opacity: 0.4;
    width: 100%;
    height: 500upx;
  }
  .tips{
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #ffffff;
    font-size: $uni-font-size-sm;
  }
}

.id-card-info{
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, .8);
  z-index: 999999 !important;
  .middle{
    width: 550upx;
    height: 600upx;
    background-color: #ffffff;
    border-radius: 20upx;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    .title{
      font-size: $uni-font-size-maxer;
      height: 100upx;
      line-height: 100upx;
      text-align: center;
      font-weight: bold;
    }
    .content{
      flex: 1;
      width: 100%;
      padding-left: 50upx;
      box-sizing: border-box;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: flex-start;
      .item{
        display: flex;
        margin-bottom: 20upx;
        font-size: $uni-font-size-lger;
        .label{
          color: $uni-text-color-grey;
        }
        .value{
          margin-left: 10upx;
        }
      }
    }
    .footer{
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      padding: 20upx;
      .btn{
        width: 450upx;
        height: 80upx;
        border-radius: 60upx;
        line-height: 80upx;
        text-align: center;
      }
      .sure{
        color: #ffffff;
        background-color: $uni-bg-color-global;
        margin-bottom: 20upx;
      }
      .cancel{
        color: grey;
        background-color: $uni-bg-color-grey;
      }
    }
  }
}
</style>

有小伙伴私信我要图片,安排:

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值