身份证上传识别的流程:
1、手机拍照
2、将照片上传给服务器,服务器调用阿里云或者百度的ocr身份证识别接口
这里只讲述如何用h5拍照,并将图片转换成base64,上传。

拍照压缩转base64主要看这几个方法:upload 、imgPreview 、startParse、rotateImg 、compress方法

<template><div class="bg-fff" style="min-height:100%;"><div class="p-15"><div class="return-icon" @click="back"><i class="iconfont icon-houtui f16"></i></div><div class="center f14 c-333"> 拍摄/上传客户二代身份证</div><div class="img-control mt-20"  v-if="headerImage"><div class="img-control-tool" @click="handleDelete"><i class="iconfont icon-shanchu c-666 f22"></i></div><div class="img-container"><img :src="headerImage" alt="" class="picture"><!-- <div class="picture" :style="'backgroundImage:url('+headerImage+')'"></div> --></div><div class="img-control-tool" @click="showMagnifyIdCard=true"><i class="iconfont icon-fangda c-666 f22"></i></div></div><div style="margin-top:20px;"><div class="beautify-upload  center" v-if="!headerImage"><input type="file" id="upload"  ref="uploadInput" accept="image/*" capture="camera"   @change="upload" v-if="android"><input type="file" id="upload"  ref="uploadInput" accept="image/*"   @change="upload" v-else></div><div class="mul-area" v-if="headerImage&&!hasServerMsg" ><button @click="startParse" class="blue-btn mul-btn">开始识别</button></div></div><div class="confirm-msg" v-if="hasServerMsg"><h3 style="margin-bottom:10px;" class="f14">请确认身份证信息(双击内容可修改):</h3><div class="row"><div class="sort">姓名</div><div class="content" contenteditable="true">{{auth.name}}</div></div><div class="row"><div class="sort">身份证</div><div class="content" contenteditable="true">{{auth.num}}</div></div><div><button class="confirm-btn" @click="confirm">确认并返回</button></div></div><div class="id-card-magnify" v-show="showMagnifyIdCard" @click="showMagnifyIdCard=false"><div class="close" @click="showMagnifyIdCard=false"><i class="iconfont icon-guanbi f35"></i></div><img :src="headerImage" alt="" class="magnify-picture"></div></div></div>
</template><script>
import api from '@/service/microInsurance'
import * as util from '@/scripts/util'
import {mapState} from 'vuex'/* eslint-disable */
export default {data () {return {headerImage: '',picValue: '',showMagnifyIdCard:false,hasServerMsg:false,auth:{},android:util.browser.versions.android}},mounted () {},methods: {back(){this.$emit('close')this.clearData()},confirm(){this.$emit('confirm',{...this.auth})this.clearData()},clearData(){this.headerImage=''this.picValue =''this.showMagnifyIdCard = falsethis.hasServerMsg =falsethis.auth ={}},upload (e) {let files = e.target.files || e.dataTransfer.filesif (!files.length) returnthis.picValue = files[0]this.imgPreview(this.picValue)console.log(this.picValue)},imgPreview (file) {let self = thislet Orientation// 去获取拍照时的信息,解决拍出来的照片旋转问题EXIF.getData(file, function () {Orientation = EXIF.getTag(this, 'Orientation')})// 看支持不支持FileReaderif (!file || !window.FileReader) returnif (/^image/.test(file.type)) {// 创建一个readerlet reader = new FileReader()// 将图片2将转成 base64 格式reader.readAsDataURL(file)// 读取成功后的回调reader.onloadend = function () {let result = this.resultlet img = new Image()img.src = result//  判断图片是否大于100K,是就直接上传,反之压缩图片if (this.result.length <= (100 * 1024)) {self.headerImage = this.result} else {img.onload = function () {let data = self.compress(img, Orientation)self.headerImage = data}}}}},startParse(){this.postImg()},postImg () {let base64 =''let index =  this.headerImage.indexOf(',')if(index!==-1){base64 = this.headerImage.substring(index+1)}if(base64){// 这里写接口api.orcIdcard({authorization:this.authorization,openId:this.openId,base64:base64}).then(util.filterBackendData).then(res=>{this.hasServerMsg=truethis.auth =res}).catch(err=>{this.showToast(err)})}},rotateImg (img, direction, canvas) {// 最小与最大旋转方向,图片旋转4次后回到原方向const minStep = 0const maxStep = 3if (img == null) return// img的高度和宽度不能在img元素隐藏后获取,否则会出错let height = img.heightlet width = img.widthlet step = 2if (step == null) {step = minStep}if (direction === 'right') {step++// 旋转到原位置,即超过最大值step > maxStep && (step = minStep)} else {step--step < minStep && (step = maxStep)}// 旋转角度以弧度值为参数let degree = step * 90 * Math.PI / 180let ctx = canvas.getContext('2d')switch (step) {case 0:canvas.width = widthcanvas.height = heightctx.drawImage(img, 0, 0)breakcase 1:canvas.width = heightcanvas.height = widthctx.rotate(degree)ctx.drawImage(img, 0, -height)breakcase 2:canvas.width = widthcanvas.height = heightctx.rotate(degree)ctx.drawImage(img, -width, -height)breakcase 3:canvas.width = heightcanvas.height = widthctx.rotate(degree)ctx.drawImage(img, -width, 0)break}},compress (img, Orientation) {let canvas = document.createElement('canvas')let ctx = canvas.getContext('2d')// 瓦片canvaslet tCanvas = document.createElement('canvas')let tctx = tCanvas.getContext('2d')let initSize = img.src.lengthlet width = img.widthlet height = img.height// 如果图片大于四百万像素,计算压缩比并将大小压至400万以下let ratioif ((ratio = width * height / 4000000) > 1) {console.log('大于400万像素')ratio = Math.sqrt(ratio)width = width/ratioheight = height/ratio} else {ratio = 1}canvas.width = widthcanvas.height = height//        铺底色ctx.fillStyle = '#fff'ctx.fillRect(0, 0, canvas.width, canvas.height)// 如果图片像素大于100万则使用瓦片绘制let countif ((count = width * height / 1000000) > 1) {console.log('超过100W像素')count = ~~(Math.sqrt(count) + 1) // 计算要分成多少块瓦片//            计算每块瓦片的宽和高let nw = ~~(width / count)let nh = ~~(height / count)tCanvas.width = nwtCanvas.height = nhfor (let i = 0; i < count; i++) {for (let j = 0; j < count; j++) {tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh)ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh)}}} else {ctx.drawImage(img, 0, 0, width, height)}// 修复ios上传图片的时候 被旋转的问题if (Orientation !== '' && Orientation !== 1) {switch (Orientation) {case 6:// 需要顺时针(向左)90度旋转this.rotateImg(img, 'left', canvas)breakcase 8:// 需要逆时针(向右)90度旋转this.rotateImg(img, 'right', canvas)breakcase 3:// 需要180度旋转this.rotateImg(img, 'right', canvas)// 转两次this.rotateImg(img, 'right', canvas)break}}// 进行最小压缩let ndata = canvas.toDataURL('image/jpeg', 0.1)console.log('压缩前:' + initSize)console.log('压缩后:' + ndata.length)console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + '%')tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0return ndata},handleDelete(){this.headerImage='';this.deleteServerMsg()},deleteServerMsg(){this.hasServerMsg=false;}},computed:{...mapState(['authorization','openId'])}
}
</script><style lang="less">
*{margin: 0;padding: 0;
}
.return-icon{position:absolute;top:10px;left:10px;color:#666;// color:#1E88C7;// background:#fff;// border:2px solid #eee;// border-radius: 50%;width:80px;height:80px;line-height:80px;text-align: center;
}
.img-control{display: flex;align-items:center;
}
.img-control-tool{flex:1;text-align: center;
}
.img-container{overflow: hidden;position: relative;width:60%;margin:0 auto;/* height:600px; */border: 1px solid #d5d5d5;
}
.picture {width: 100%;height:300px;vertical-align: middle;/* overflow: hidden;background-position: center center;background-repeat: no-repeat;background-size: cover; */
}
.beautify-upload{position: relative;color: #1E88C7;text-decoration: none;text-indent: 0;background: url('./img/upload-idcard.png') no-repeat;width:250PX;height:150PX;margin:0 auto;background-size:100% 100%;
}
.beautify-upload input {position: absolute;font-size: 100px;right: 0;top: 0;left:0;bottom:0;opacity: 0;
}
.mul-area{display: flex;
}
.mul-area>button{flex:1;
}
.mul-btn{height:88px;line-height:88px;border-radius: 8px ;
}
.blue-btn{display: block;background:#0099ff;border: 1px solid #0099ff;color:#fff;
}
.id-card-magnify{width:100%;background:rgba(0,0,0,.8);position:absolute;left:0;top:0;bottom:0;display: flex;align-items: center;
}
.magnify-picture{width:100%;height:auto;
}
.close{position: absolute;right:10px;top:10px;width:100px;height:100px;text-align: center;color:#fff;
}
.confirm-msg{font-size:14PX;margin-top:20px;padding:30px 20px;// background: #fff;color:#454545;.row{display: flex;border:2px solid #e6e6e6;margin-bottom:-1px;.sort{padding:10px;flex-basis: 120px;border-right:2px solid #e6e6e6;text-align: center}.content{flex:1;padding:10px;text-align: center;}}.confirm-btn{padding:20px;background:#0099ff;color:#fff;width:100%;font-size:15PX;margin-top:40px;border-radius: 8px;}
}</style>

common.less文件:

body, div, span, header, footer, nav, section, aside, article, ul, dl, dt, dd, li, a, p, h1, h2, h3, h4,h5, h6, i, b, textarea, button, input, select, figure, figcaption, {padding: 0;margin: 0;list-style: none;font-style: normal;text-decoration: none;border: none;font-weight: normal;font-family: -apple-system-font,Helvetica Neue,sans-serif;box-sizing: border-box;-webkit-tap-highlight-color:transparent;-webkit-font-smoothing: antialiased;&:hover{outline: none;}}/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar
{width: 0px;height: 0px;background-color: #F5F5F5;
}/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track
{-webkit-box-shadow: inset 0 0 1px rgba(0,0,0,0);border-radius: 10px;background-color: #F8F8F8;
}/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb
{border-radius: 10px;-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);background-color: #555;
}input[type="button"], input[type="submit"], input[type="search"], input[type="reset"] {-webkit-appearance: none;
}textarea { -webkit-appearance: none;}html,body{height: 100%;width: 100%;
}.clear:after{content: '';display: block;clear: both;
}.clear{zoom:1;
}
button{outline:none;
}
.back_img{background-repeat: no-repeat;background-size: 100% 100%;
}.margin{margin: 0 auto;
}.left{float: left;
}.right{float: right;
}
.center{text-align: center;
}
.hide{display: none;
}
.show{display: block;
}
.text-right{text-align: right;
}
.f12{font-size:12px;
}
.f14{font-size:14px;
}
.f15{font-size:15px;
}
.f16{font-size:16px;
}
.f20{font-size:20px;
}
.f22{font-size:22px;
}
.f16{font-size:16px;
}
.f35{font-size:35px;
}
.f37{font-size:37px;
}
ul,li{list-style:none
}
.mt-5{margin-top:5px;
}
.mt-10{margin-top:10px;
}
.mt-20{margin-top:20px;
}
.ml-5{margin-left:5px;
}
.ml-10{margin-left:10px;
}
.ml-20{margin-left:20px;
}
.mr-10{margin-right:10px;
}
.pt-10{padding-top:10px;
}
.p-15{padding:15px;
}
.p-10{padding:10px;
}
.bold{font-weight: bold;
}
.bg-fff{background:#fff;
}
.is-danger{color:red;
}
.vertical-md{vertical-align: middle;
}
a:hover, a:visited, a:link, a:active,a {text-decoration: none;color: #444;
}
.c-333{color:#333;
}
.c-666{color:#666;
}
.c-999{color:#999;
}
.c-purple{color:#f171ae;
}
.txt-ellipsis{overflow: hidden;text-overflow:ellipsis;white-space: nowrap;
}

H5身份证上传识别功能相关推荐

  1. uniapp h5拍照上传照片

    前段时间公司要弄一个uniapp的H5拍照上传的功能,看这位博主 常德_威少 的博客完成了(博客地址:使用canvas压缩图片大小_常德_威少的博客-CSDN博客_canvas压缩图片),于是想把我写 ...

  2. uni-app 上传识别身份证信息

    最近在做一款小程序,需要用到上传识别身份证的功能,但是本人对uni-app 不是特别熟悉,求大神帮忙!!!  万分感谢!!!

  3. 超详细的实现上传文件功能教程,文件上传实现。

    重要声明:本文章仅仅代表了作者个人对此观点的理解和表述.读者请查阅时持自己的意见进行讨论. 本文更新不及时,请到原文地址浏览:<超详细的实现上传文件功能教程,文件上传实现.>. 一.文件上 ...

  4. 教你如何实现c#文件上传下载功能

    简单介绍一下c#文件上传下载功能实现. NuGet 安装SqlSugar Model文件下新建 DbContext 类 public class DbContext {public DbContext ...

  5. Android WebView 支持H5图片上传input type=file

    2019独角兽企业重金招聘Python工程师标准>>> Android WebView 缓存处理 Android WebView 支持H5图片上传<input type=&qu ...

  6. JavaWeb实现文件上传下载功能实例解析

    转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能 ...

  7. webuploader+PHP实现超大文件分片上传的功能

    在开发<工单地图>的时候,后台平面图上传的功能需要处理10M以上大小的文件上传,单个超大文件上传的时候容易出现各种问题,后来采用了分片上传的思路.将大文件分成多个小的文件分片,逐个上传到服 ...

  8. java 转发上传文件_Java 发送http请求上传文件功能实例

    废话不多说了,直接给大家贴代码了,具体代码如下所示: package wxapi.WxHelper; import java.io.BufferedReader; import java.io.Dat ...

  9. 移动端H5图片上传的那些坑

    上周做一个关于移动端图片压缩上传的功能.期间踩了几个坑,在此总结下. 大体的思路是,部分API的兼容性请参照caniuse: 利用FileReader,读取blob对象,或者是file对象,将图片转化 ...

最新文章

  1. 元素水平垂直居中的方法
  2. 【Android 逆向】selinux 进程保护 ( selinux 进程保护 | 宽容模式 Permissive | 强制模式 Enforcing )
  3. 计算机技术是双证,计算机技术在职研究生单证可以转双证吗
  4. 第1章-导言-习题1.13-1.17
  5. Kotlin入门(32)网络接口访问
  6. 论文笔记-LSHTC: A Benchmark for Large-Scale Text Classification-2015
  7. oracle中创建视图的语句,求Oracle创建视图有关语句
  8. Inspect(VB.NET、C#版)软件的的下载和使用
  9. 基于神经网络的指纹识别,指纹比对技术何时出现
  10. 大学生必看:基础IT技术文章300篇大合集!【包含信息/编码、IP/组网、程序逻辑、Web基础等】
  11. 面试题:十瓶牛奶每天至少喝一瓶,直到喝完到底有多少种喝法
  12. 基于K-Means聚类算法对NBA球员数据的聚类分析
  13. 050 XSS通关小游戏——xss challenge
  14. python网页自动填写_Windows下使用python3 + selenium实现网页自动填表功能
  15. C++实现Socket连接通信
  16. 组合数学_排列与组合
  17. 自监督论文阅读笔记DisCo: Remedy Self-supervised Learning on Lightweight Models with Distilled Contrastive
  18. 基于SSM网络蛋糕商城管理系统
  19. Mutiselect下拉复选框(保存和设置默认选中项)
  20. 微软 2020 校园招聘正式启动

热门文章

  1. 多媒体课件是不是计算机软件,计算机应用基础与信息处理多媒体课件制作.doc...
  2. css定位-css新增选择器(内减,属性,伪类,2d变换,过渡)
  3. windows11账户登录不上去怎么办?
  4. 《Learning Enriched Features for Real Image Restoration and Enhancement》
  5. snownlp对天猫商品评论数据进行情感分析(附源码)
  6. canvas小虫子(利用canvas形成多个形状类似虫子的线条)
  7. 辽宁省抚顺市谷歌高清卫星地图下载
  8. STL mismatch算法
  9. 2020胡润80后白手起家富豪榜公布,掌门教育张翼强势登榜
  10. 解决Vue history模式下使用嵌套路由打包部署后刷新页面为空白页