微信小程序图片上传以及身份证识别

在开发过程中需要对用户进行实名认证,查阅微信开放文档apiwx.chooseImage(Object object) 进行了简单开发 ,具体的参数以及回调参数 文档中都有详细介绍 (wx.chooseImage官方文档介绍)

里面包含了图片压缩,身份证自动识别 表单验证等 废话不多说直接上代码吧 方便你我他

  1. 整活第一步(wxml)

<view class="list">
	<view>
		<image src="{{imgPath || 'https:xxxxxx/api/file/getFileAuth?bucketName=jiakaozhijia&fileName=cm/SubjectOne/5D76F2A53E84D384061DB68F5B4EEA80'}}" alt="" class="idcard-img" mode="aspectFit"></image>
		<view class="upload">
			<view class="upload-btn">
				<view class="upload-btn-text">上传身份证人脸照</view>
				<view name="file" class="upload-file" bindtap="choosePic"></view>
			</view>
		</view>
	</view>
	<view class="vertical-separator"></view>
	<view class="item">
		<view class="item-label">
			姓名
		</view>
		<view class="item-input">
			<input type="text" maxlength="10" placeholder="可通过上传身份证识别" model:value="{{name}}" id="realName"></input>
		</view>
	</view>
	<view class="item">
		<view class="item-label">
			性别
		</view>
		<view class="item-input">
			<radio-group bindchange="radioChange" style="height: 1.6rem; padding: 0.1rem 0; display: flex; font-size: 0.9rem;">
				<label style="width: 35%;">
					<radio value="男" style="transform:scale(0.8)" checked="{{sex == '男'}}" color="#2A67F8"/></label>
				<label style="width: 65%;">
					<radio value="女" style="transform:scale(0.8)" checked="{{sex == '女'}}" color="#2A67F8"/></label>
			</radio-group>
		</view>
	</view>
	<view class="item">
		<view class="item-label">
			身份证
		</view>
		<view class="item-input">
			<input type="text" maxlength="18" placeholder="可通过上传身份证识别" model:value="{{idcard}}" id="idCardNo" bindblur="checkIdcard"></input>
		</view>
	</view>
		<view class="item">
		<view class="item-label">
			住址
		</view>
		<view class="item-input" style="height: 3rem;">
			<textarea type="text" maxlength="50" placeholder="可通过上传身份证识别" model:value="{{address}}" id="address" style="height: 100%; width: 100%; word-break: break-all; word-wrap: break-word;"></textarea>
		</view>
	</view>
	<view class="item" style="margin: 0; padding-left: 1rem;">
		<view class="item-label">
			手机号码
		</view>
		<view class="item-input">
			<input type="number" maxlength="11" placeholder="请输入手机号码" model:value="{{phone}}" id="phone" bindinput="phoneInput"></input>
		</view>
	</view>
	<view class="pay-btn" bindtap="openNextPage">
		继续采集
	</view>
</view>

<canvas canvas-id="canvas" style="width:{{cWidth}}px;height:{{cHeight}}px;position: absolute;left:-10000px;top:-10000px;"></canvas>
  1. 整活第二步(wxss)
.header {
  height: 2.25rem;
  line-height: 2.25rem;
  background-color: #fff;
  text-align: center;
}

.list {
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

.upload {
  height: 2.5rem;
  padding-bottom: 0.75rem;
}

.upload-btn {
  position: relative;
  top: 0.5rem;
  height: 2rem;
  text-align: center;
  padding: 0;
}

.upload-btn-text {
  display: block;
  position: absolute;
  left: 30%;
  padding: 0;
  width: 40%;
  height: 2rem;
  line-height: 2rem;
  border-radius: 4px;
  font-size: 0.8rem;
  color: #fff;
  background-image: linear-gradient(270deg, #3F86FE 0%, #64ADF6 99%);
  border: none !important;
}

.idcard-img {
  width: 90%;
  height: 12rem;
  margin-left: 5%;
}

.upload-file {
  display: block;
  position: absolute;
  left: 30%;
  padding: 0;
  width: 40%;
  height: 2rem;
  line-height: 2rem;
  border-radius: 4px;
  padding: 0;
  opacity: 0;
  border: none !important;
}

.vertical-separator {
  height: 10px;
  background-color: #f5f5f5;
}

.item {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  margin: 0 0 0 1rem;
}

.item::after {
  width: 100%;
  height: 1px;
  background-color: #ddd;
  display: block;
  content: '';
  position: absolute;
  top: auto;
  right: auto;
  bottom: 0;
  left: 0;
  z-index: 2;
  -webkit-transform-origin: 50% 100%;
  transform-origin: 50% 100%;
  pointer-events: none;
  transform: scaleY(0.5);
}

.item-label {
  width: 25%;
  height: 2.8rem;
  line-height: 2.8rem;
  text-align: left;
  font-size: 0.9rem;
  color: #27344C;
  font-weight: bold;
}

.item-input {
  width: 75%;
  padding: 0.5rem 1rem;
  height: 1.8rem;
}

.item-input input {
  height: 100%;
}

.pay-btn {
  margin: 1.5rem auto;
  width: 90%;
  height: 2rem;
  line-height: 2rem;
  background-image: linear-gradient(270deg, #3F86FE 0%, #64ADF6 99%);
  border-radius: 1.25rem;
  color: #fff;
  font-size: 0.8rem;
  font-weight: bold;
  text-align: center;
}

  1. 整活第三步(js)

const app = getApp();
Page({
  /**
   * 页面的初始数据
   */
  data: {
    imgPath: '',
    name: '',
    age: '',
    sex: '',
    idcard: '',
    phone: '',
    hospitalId: '',
    account: '',
    address: '',
    cWidth: '',
    cHeight: ''
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log('options===', options);
    if (options.q) {
      let url = decodeURIComponent(options.q);
      let search = url.match(/\?(.*)$/);
      let arr1 = search[1].split('&');
      let obj = {};
      for (let item of arr1) {
        let arr2 = item.split('=');
        obj[arr2[0]] = arr2[1];
      }
      console.log(obj);
      this.setData({
        hospitalId: obj.hospitalId,
        account: obj.account
      });
    }
  },
  /**
   * 选择图片上传
   */
  choosePic: function (e) {
    var that = this;
    wx.chooseImage({
      count: 1,
      sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res) {
        console.log(res);
        var size = res.tempFiles[0].size / 1024;
        console.log('图片大小=', size + 'k');
        wx.getImageInfo({
          src: res.tempFilePaths[0],
          success: function (res) {
            console.log(res);
          }
        });
        if (size > 1024) {
          that.getImgBase64(res.tempFilePaths[0]);
        } else {
          that.getImgBase64(res.tempFilePaths[0]);
        }
      }
    });
  },
  /**
   * 识别身份证
   */
  identifyIdCard: function (base64Str) {
    wx.showLoading({
      title: '身份证识别中',
    });
    var that = this;
    wx.request({
      url: app.globalData.thirdApiPrefix + 'api/idcard',//这里换上你们自己的身份证识别地址
      data: {  imgBase64: base64Str, idcardSide: 'front' },
      method: 'post',
      header: {
        'content-type': "application/x-www-form-urlencoded"
      },
      dataType: 'json',
      success: function (ret) {
        wx.hideLoading();
        if (ret && ret.data) {
          if (ret.data.image_status === 'normal') {
            that.setData({
              name: ret.data.words_result['姓名'].words,
              sex: ret.data.words_result['性别'].words,
              age: new Date().getFullYear() - ret.data.words_result['出生'].words.substr(0, 4),
              idcard: ret.data.words_result['公民身份号码'].words,
              address: ret.data.words_result['住址'].words,
              imgPath: 'data:image/png;base64,' + base64Str
            });
            wx.showToast({
              title: '识别成功,请确认信息是否正确',
              icon: 'none',
              duration: 3000
            });
          } else {
            wx.showToast({
              title: '无法识别,请重新上传',
              icon: 'none',
              duration: 1500
            });
          }
        } else {
          wx.showToast({
            title: '服务异常',
            icon: 'none',
            duration: 1500
          });
        }
      },
      fail: function (res) {
        wx.hideLoading();
        console.log(res);
        wx.showToast({
          title: '网络故障,请重试',
          icon: 'none',
          duration: 1500
        });
      },
      complete: function (res) { },
    });
  },
 /**
   * 跳转更多信息页面
   */
  openNextPage: function () {
    let that = this;
    if (!that.data.name) {
      wx.showToast({
        title: '请输入身份证姓名',
        icon: 'none',
        duration: 1500
      });
      return;
    }
    if (!(/^[\u4e00-\u9fa5]{2,10}$/.test(that.data.name))) {
      wx.showToast({
        title: '身份证姓名格式错误',
        icon: 'none',
        duration: 1500
      });
      return;
    }
    if (!that.data.sex) {
      wx.showToast({
        title: '请选择性别',
        icon: 'none',
        duration: 1500
      });
      return;
    }
    if (!that.data.idcard) {
      wx.showToast({
        title: '请输入身份证号',
        icon: 'none',
        duration: 1500
      });
      return;
    }
    if (!that.data.address) {
      wx.showToast({
        title: '请输入身份证住址',
        icon: 'none',
        duration: 1500
      });
      return;
    }
    if (!that.data.phone) {
      wx.showToast({
        title: '请输入手机号',
        icon: 'none',
        duration: 1500
      });
      return;
    }
    if (!(/^[1][3456789][0-9]{9}$/.test(that.data.phone))) {
      wx.showToast({
        title: '请输入正确的手机号',
        icon: 'none',
        duration: 1500
      });
      return;
    }
    let url = 'third/physical/site/examinationByScanCode';
    let params = {
      name: that.data.name,
      sex: that.data.sex,
      idcardNo: that.data.idcard,
      phone: that.data.phone,
      channel: 7,
      hospitalId: that.data.hospitalId,
      account: that.data.account,
      address: that.data.address
    };
    wx.showLoading({
      title: '加载中',
    });
    console.log('生成订单入参:', params);
    app.requestFunction(url, params, 'post', function (ret) {
      wx.hideLoading();
      console.log('生成订单出参:', ret);
      if (ret && ret.data) {
        if (ret.data.code === 0) {
          // 跳转页面
          wx.navigateTo({
            url: 'pay?orderId=' + ret.data.examinationSite.id + '&hospitalName=' + ret.data.hospital.shortName +
              '&insertDt=' + ret.data.examinationSite.insertDt.substr(0, 19) + '&price=' + ret.data.hospital.examinationPrice
          });
        } else {
          wx.showToast({
            title: ret.data.msg,
            icon: 'none',
            duration: 1500
          });
        }
      }
    });
    // wx.navigateTo({
    //   url: 'more_info?hospitalId=' + that.data.hospitalId + '&account=' + that.data.account + '&name=' + that.data.name + '&sex=' + that.data.sex + '&idcard=' + that.data.idcard + '&address=' + that.data.address
    // });
  },

  /**
   * 输入手机号绑定
   */
  phoneInput: function (e) {
    var that = this;
    if (e.detail.value.length > 0) {
      that.setData({
        phone: e.detail.value
      });
    }
  },
  imgCompress: function (imgPath) {
    var that = this;
    wx.getImageInfo({
      src: imgPath,
      success: function (res) {
        console.log(res);
        //---------利用canvas压缩图片--------------
        var ratio = 2;
        var canvasWidth = res.width //图片原始长宽
        var canvasHeight = res.height
        while (canvasWidth > 2000 || canvasHeight > 2000) {// 保证宽高在2000以内
          canvasWidth = Math.trunc(res.width / ratio)
          canvasHeight = Math.trunc(res.height / ratio)
          ratio++;
        }
        that.setData({
          cWidth: canvasWidth,
          cHeight: canvasHeight
        })
        //----------绘制图形并取出图片路径--------------
        var ctx = wx.createCanvasContext('canvas')
        ctx.drawImage(res.path, 0, 0, canvasWidth, canvasHeight)
        ctx.draw(false, setTimeout(function () {
          wx.canvasToTempFilePath({
            canvasId: 'canvas',
            destWidth: canvasWidth,
            destHeight: canvasHeight,
            fileType: 'jpg',
            success: function (res) {
              console.log(res.tempFilePath)//最终图片路径
              that.getImgBase64(res.tempFilePath);
            },
            fail: function (res) {
              console.log(res.errMsg)
            }
          })
        }, 100))
      },    //留一定的时间绘制canvas
      fail: function (res) {
        console.log(res.errMsg)
      }
    });
  },
  getImgBase64: function (imgUrl) {
    var that = this;
    // 图片转base64
    wx.getFileSystemManager().readFile({
      filePath: imgUrl, //选择图片返回的相对路径
      encoding: "base64",//这个是很重要的
      success: res => { //成功的回调,返回base64格式
        console.log('压缩后', res.data.length / 1024 * 0.75 + 'k');
        that.identifyIdCard(res.data);
      }
    })
  },
  checkIdcard(e) {
    if (e.detail.value && !(/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(e.detail.value))) {
      wx.showToast({
        title: '身份证格式错误',
        icon: 'none',
        duration: 1500
      });
    }
  },
    /**
    * 选择性别
    */
   radioChange(e) {
    let that = this;
    console.log('性别===', e.detail.value);
    that.setData({
      sex: e.detail.value
    });
  },
})

最后的效果图

微信小程序图片上传以及身份证识别_第1张图片
如有疑问欢迎滴滴留言

你可能感兴趣的:(微信小程序,小程序)