项目中用到的"高拍仪"和"身份证读卡器"浅记
1.高拍仪
第一步:下载驱动 CameraService.exe,用到的是哲林高拍仪。
第二步:启动高拍仪驱动,连接高拍仪设备。
第三步:项目引入使用
utils/camera.js
import $ from 'jquery' var iCutType = '1' function BrowserType() { var userAgent = navigator.userAgent //取得浏览器的userAgent字符串 if (userAgent.indexOf('Firefox') > -1) return 'Firefox' if (userAgent.indexOf('Chrome') > -1) return 'Chrome' return 'IE' } function IsIE() { if (BrowserType() == 'IE') return true else return false } var phi = 0 var camidx = 0 var isIE = false //初始化 export function Init() { isIE = IsIE() SetAutoCut(true) } function SetAutoCut(bShow) { //自动切边 var params = '{"cutpage":"' + (bShow ? 'true' : 'false') + '"}' // var url = 'http://127.0.0.1:38088/param=set' $.ajax({ type: 'post', url: url, dataType: 'json', data: params, success: function(data) {} }) } export function GrabImage(img) { //拍照 var jsCustomRect = '' if (iCutType == '2') jsCustomRect = ', "custom_rect":' + document.getElementById('js_custom_rect').value var strStorageInfo = '{ "xdpi":"200", "ydpi":"200", "jpg_quality":"60" }' var strImageProcess = '{"cut_type":"' + iCutType + '", "multi_object":"1", "rotate":"' + phi.toString() + '"' + jsCustomRect + '}' var params = '{"camidx":"' + camidx.toString() + '","make_uuid":"1","image_storage_info":' + strStorageInfo + ',"image_process_info":' + strImageProcess + '}' var url = 'http://127.0.0.1:38088/video=grabimage' var imgList = [] $.ajax({ type: 'post', url: url, dataType: 'json', data: params, async: false, success: function(data) { if (data.code != 0) { } else { console.log('图像数量:' + data.image_count) var images = data.images var iCount = data.image_count console.log(data.images) var strImageList = '' for (var i = 0; i < iCount; i++) { strImageList += '<img src="data:image/jpg;base64,' + images[i].base64 + '" width=95% />' // if (typeof(images[i].uuid) != "undefined") // document.getElementById("pdf_input").value = images[i].uuid; imgList.push(images[i].base64) } } } }) return imgList } // 旋转镜头 export function rotating() { if(isIE) //ie浏览器 { phi = (phi + 90) % 360; setXformClass(); } else { phi = (phi + 90) % 360; setXformClass(); if (phi % 180) { $('.xform-p').addClass('rotated'); } else { $('.xform-p').removeClass('rotated'); } } } function setXformClass () { if(isIE) //ie浏览器 { var iAngle = showVideoOcx.GetVideoRotate() + 90; if (iAngle > 270) { iAngle -= 360; } showVideoOcx.SetVideoRotate(iAngle); } else { $('.xform').each(function(idx,el) { el.className = "xform x" + "-rotated-" + phi; }); } }
gpsc.vue组件:
<template> <div> <a-modal v-model="visible" title="" @cancel="handleClose" :confirm-loading="confirmLoading" width="800px" :footer="null" :closable="false" > <div class="container"> <div style="margin-bottom: 20px;display: flex;justify-content: flex-start;align-items: center;"> <a-button type="primary" @click="takephoto" v-if="show == 1"> 拍照 </a-button> <a-button type="danger" @click="del" v-if="show == 2"> 删除 </a-button> <a-button type="primary" style="margin-left: 20px;" @click="upload"> 修改名字并上传 </a-button> <!-- <a-button>点击</a-button>--> <div id="xform" v-show="rotatingShow"> <a-button @click="rotatingCli" id="rotate" style="margin-left: 20px;"> <div class="btnface"></div> </a-button> </div> </div> <a-input-search placeholder="请输入文件名" size="large" @search="onSearch" style="margin-bottom: 20px" v-model="name" v-if="show1 == true" > <a-button slot="enterButton" type="primary"> 确定 </a-button> </a-input-search> <div> <p class="xform-p"></p> <div class="cont_b"> <p id="streamwrap" class="xform-p"> <img id="streamimage" class="xform" src="http://127.0.0.1:38088/video=stream&camidx=0" width="100%" height="100%" onerror="onerror=null;src='../../assets/img/app_stop.jpg'" v-if="show == 1" /> <img :src="pre + pic" v-if="show == 2" width="100%" height="100%" /> </p> </div> </div> </div> </a-modal> </div> </template> <script> import { Init, GrabImage, rotating } from '@/utils/camera' import $ from 'jquery' export default { name: '', data() { return { visible: false, pre: 'data:image/jpg;base64,', confirmLoading: false, show: 1, pic: '', show1: false, name: '', // 旋转按钮 rotatingShow: true, } }, watch: { visible(val) { if (val == true) { this.show = 1 this.pic = '' this.show1 = false this.name = '' } }, show(e) { if(e == 1) { this.rotatingShow = true }else { this.rotatingShow = false } } }, mounted() { Init(); }, methods: { // 拍照 takephoto() { let pics = GrabImage() if (pics.length == 0) { this.$message.warning('请检查设备是否连接') } else if (pics.length == 1) { this.show = 2 this.pic = pics[0] } else { this.$message.warning('暂只支持单张图片拍照') } // console.log(pics) }, rotatingCli() { rotating() }, upload() { if (this.pic != '') { this.show1 = true } else { this.$message.warning('请先拍照再上传') } }, onSearch() { const blob = this.base64ToBlob(this.pre + this.pic) const file = this.blobToFile(blob, this.name + '.png') let fileInfo = { pic: file } this.visible = false this.$emit('picOk', fileInfo) }, del() { this.show = 1 this.pic = '' }, handleClose() { this.$emit('close') }, base64ToBlob(base64Data) { let arr = base64Data.split(','), fileType = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), l = bstr.length, u8Arr = new Uint8Array(l) while (l--) { u8Arr[l] = bstr.charCodeAt(l) } return new Blob([u8Arr], { type: fileType, }) }, // blob转file blobToFile(newBlob, fileName) { let file = new window.File([newBlob], fileName, { type: 'image/gif' }) // newBlob.lastModifiedDate = new Date() // newBlob.name = fileName return file }, }, } </script> <style scoped> img.x-rotated-0 {} img.x-rotated-90 { -moz-transform: rotate(90deg); -webkit-transform: rotate(90deg); } img.x-rotated-180 { -moz-transform: rotate(180deg); -webkit-transform: rotate(180deg); } img.x-rotated-270 { -moz-transform: rotate(270deg); -webkit-transform: rotate(270deg); } img.x-mirrored-rotated-0 { -moz-transform: scaleX(-1); -webkit-transform: scaleX(-1); } img.x-mirrored-rotated-90 { -moz-transform: rotate(90deg) scaleX(-1); -webkit-transform: rotate(90deg) scaleX(-1); } img.x-mirrored-rotated-180 { -moz-transform: rotate(180deg) scaleX(-1); -webkit-transform: rotate(180deg) scaleX(-1); } img.x-mirrored-rotated-270 { -moz-transform: rotate(270deg) scaleX(-1); -webkit-transform: rotate(270deg) scaleX(-1); } img.x-flipped-rotated-0 { -moz-transform: scaleY(-1); -webkit-transform: scaleY(-1); } img.x-flipped-rotated-90 { -moz-transform: rotate(90deg) scaleY(-1); -webkit-transform: rotate(90deg) scaleY(-1); } img.x-flipped-rotated-180 { -moz-transform: rotate(180deg) scaleY(-1); -webkit-transform: rotate(180deg) scaleY(-1); } img.x-flipped-rotated-270 { -moz-transform: rotate(270deg) scaleY(-1); -webkit-transform: rotate(270deg) scaleY(-1); } img.x-flipped-mirrored-rotated-0 { -moz-transform: scale(-1,-1); -webkit-transform: scale(-1,-1); } img.x-flipped-mirrored-rotated-90 { -moz-transform: rotate(90deg) scale(-1,-1); -webkit-transform: rotate(90deg) scale(-1,-1); } img.x-flipped-mirrored-rotated-180 { -moz-transform: rotate(180deg) scale(-1,-1); -webkit-transform: rotate(180deg) scale(-1,-1); } img.x-flipped-mirrored-rotated-270 { -moz-transform: rotate(270deg) scale(-1,-1); -webkit-transform: rotate(270deg) scale(-1,-1); } .btnface { height:30px; width:30px; background:url("../../../assets/rotateicons.png") no-repeat scroll 7px 50% transparent; } #streamimage { width:520px; height: 390px; } #xform { text-align:right; margin:0 !important; display: flex; align-items: center; } #streamwrap { height:400px; display: flex; justify-content: center; } #streamwrap.rotated { height:450px } .cont_b{ display: flex; justify-content: center; } p.xform-p { width: 520px; height:5px; margin-bottom:0 !important; } p.xform-p.rotated { height:50px; margin-bottom:20px !important; } </style>
页面中:
<div @click="takephoto" class="addxfrStyle">高拍上传 <a-icon type="cloud-upload" /></div>
组件:
<gpsc ref="gpsc" @picOk="getPic"></gpsc>
takephoto() { this.$refs.gpsc.visible = true },
getPic(val) {
let temp
temp = val.pic
temp.originFileObj = val.pic
temp.originFileObj.uid = -Date.parse(new Date()) / 1000 + this.fileList.length
this.handleChange() // 正常上传组件的change方法
},
2.身份证读卡器
第一步:下载驱动 新中新webapi读卡服务3.3.2.exe,用到的是新中新读卡器。
第二步:启动驱动日志记录,连接身份证读卡器设备。
第三步:项目引入使用
安装 socket.io
npm install vue-socket.io --save
main.js
import VueSocketIO from 'vue-socket.io' Vue.use(new VueSocketIO({ debug: true, connection: 'http://127.0.0.1:5000', options: { 'timeout': 300000,'reconnectionDelayMax':1000,'autoConnect':false,'reconnectionDelay':500} }))
页面中:
<div class="ids-wrapper"> <div class="ids-inner"> <button class="ids" @click="readIdCard"> <svg t="1636960585104" :disabled="disabledDu" class="icon" viewBox="0 0 1533 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5274" width="64" height="64"><path d="M1190.8335723 106.66666665H335.5223953A122.323915 122.323915 0 0 0 213.3333333 228.85572865v549.844651a122.311656 122.311656 0 0 0 122.189062 122.176803h855.311177a122.287137 122.287137 0 0 0 122.176803-122.176803V228.85572865A122.311656 122.311656 0 0 0 1190.8335723 106.66666665z m61.076143 672.033713a61.174217 61.174217 0 0 1-61.088402 61.100661H335.5223953a61.186476 61.186476 0 0 1-61.088401-61.100661V228.86798865a61.174217 61.174217 0 0 1 61.088401-61.100661h855.311177a61.161958 61.161958 0 0 1 61.076143 61.088401z m0 0" p-id="5275" fill="#236AD7"></path><path d="M1075.3871593 527.97190565c33.002203-28.037161 54.38253-69.277655 54.382531-115.826453a152.727133 152.727133 0 1 0-305.454267 0c0 46.585576 21.368068 87.789292 54.370271 115.826453-68.517575 35.687003-115.470932 107.232641-115.470932 189.640073a30.55033 30.55033 0 1 0 61.100661 0 152.739393 152.739393 0 1 1 305.466526 0 30.55033 30.55033 0 0 0 61.100661 0c0-82.407432-46.965616-153.95307-115.458673-189.640073z m-190.020113-115.826453a91.638732 91.638732 0 1 1 91.626473 91.638731 91.626473 91.626473 0 0 1-91.626473-91.638731z m-152.739393-91.650992h-366.554927a30.55033 30.55033 0 0 0 0 61.100661h366.554927a30.55033 30.55033 0 1 0 0-61.100661z m-30.55033 152.739393H366.0727263a30.55033 30.55033 0 1 0 0 61.088402h336.004597a30.55033 30.55033 0 1 0 0-61.088402z m-91.638732 152.751652H366.0727263a30.55033 30.55033 0 1 0 0 61.100661h244.365865a30.55033 30.55033 0 1 0 0-61.100661z m0 0" p-id="5276" fill="#236AD7"></path></svg> <span>读取身份证</span> </button> </div> </div>
const Base64 = require("js-base64").Base64;
openNotificationWithIcon(type,content) {
this.$notification[type]({
message: content,
description:'',
});
},
//读取身份证 readIdCard() { this.disabledDu = true // if(!this.xfrxx.xm) { // this.openNotificationWithIcon('error','请放入身份证!') // } this.$socket.open(); // 开始连接socket this.$socket.emit("startRead"); //发布消息-开始读取 this.sockets.subscribe("card message", (msg) => { console.log('111') //订阅消息,返回的是服务端发送的消息 var data = Base64.decode(msg); var data = JSON.parse(data); this.idMsgShow(data) this.openNotificationWithIcon('success','身份证读取成功!') this.$socket.emit("stopRead"); //发布消息-结束读取 this.sockets.unsubscribe('card message'); this.disabledDu = false }); }, //身份证信息回显 idMsgShow(data) { console.log(data,'idMsgShowData') // return //信访人信息回显 this.xfrxx.xm = data.name this.xfrxx.zjlx = '01' this.xfrxx.zjhm = data.cardno this.xfrxx.xb = data.sex == '男'?'1':'2' // this.xfrxx.csrq = moment(data.born) this.xfrxx.hkszd = data.address this.mzList.forEach(item => { if(item.text == data.nation + '族'){ this.xfrxx.mz = item.value } }) },