vue3 添加读卡器身份证设备和拍照

 首先安装读卡器驱动

去官网下载安装包服务下载_华视电子

原文连接:

http://t.csdnimg.cn/YoSu2icon-default.png?t=O83Ahttp://t.csdnimg.cn/YoSu2

新建reader.js文件

 3.js文件引入vue中,调用readIdCard方法读取身份证信息

const fileList = reactive({
  // 文件ID
  idCard: '',
  // 文件名称
  nameCard: '',
  // base64
  base64Card: '',
})


// 链接身份证读卡器
const connectCard = () => {
  const loading = ElLoading.service({
    lock: true,
    text: '正在链接设备,请稍后',
    background: 'rgba(0, 0, 0, 0.7)'
  })
  // 链接读卡器
  openDevice((res: IConnectRes) => {
    if (res.resultFlag === 0) {
      loading.close()
      readCardInfo()
    } else {
      loading.close()
      ElMessage({
        showClose: true,
        message: '无法连接到身份证设备!',
        type: 'error'
      })
    }
  })
}

//读取身份证
const readCardInfo = () => {
  const loading = ElLoading.service({
    lock: true,
    text: '正在读取,请稍后',
    background: 'rgba(0, 0, 0, 0.7)'
  })
  readIdCard((res: ICardInfo) => {
    if (res.resultFlag === 0) {
      loading.close()
      fileList.idCard= res.certNumber
      fileList.nameCard= res.partyName
      fileList.base64Card= res.identityPic
    } else {
      loading.close()
      ElMessage({
        showClose: true,
        message: '身份证读取失败,重新读取!',
        type: 'error'
      })
    }
  })
}

4.调用电脑的摄像头 拍照

原文连接:

http://t.csdnimg.cn/5w4ZSicon-default.png?t=O83Ahttp://t.csdnimg.cn/5w4ZS

<template>
  <Dialog
    :title="`拍照`"
    v-model="dialogVisible"
    @dialog-open="dialogShow()"
    :width="'840px'"
    :max-height="606"
    id="loading"
  >
    <div>
      <video id="video" v-show="!state.isCanvas" class="w-100% h-600px"></video>
      <canvas id="canvas" class="display-none w-100%"></canvas>
    </div>
    <div class="output" v-show="state.isCanvas">
      <img id="photo" class="w-100% h-600px block" />
    </div>
    <template #footer>
      <ElButton size="large" @click="close()" class="user-lg-size">取消</ElButton>
      <ElButton size="large" @click="takePhone()" type="primary" class="user-lg-size"
        >拍照并保存</ElButton
      >
    </template>
  </Dialog>
</template>
<script setup lang="ts">
import { Dialog } from '../../Dialog'
import { ref, reactive, nextTick, onMounted } from 'vue'
import { ElLoading, ElMessage, ElButton } from 'element-plus'
import { videoList } from './types'

const emit = defineEmits(['get-photo'])
const dialogVisible = ref(false)
//摄像头相关
const state = reactive({
  imgSrc: '',
  blobFile: '',
  preViewVisible: false,
  isCanvas: false,
  dataurl: undefined,
  loadingInstance: false
})
const video = ref()
const canvas = ref()
const ctx = ref()
const streaming = ref(false)
const photo = ref()
const cameraId: any = ref()
const loading = ref()
//将截图缩放到指定宽度
const width = 2500
let height = 0
//获取摄像头列表
const videoArr = reactive<videoList>({
  list: [] as any
})
// 弹框显示
const show = () => {
  // 显示弹框
  dialogVisible.value = true
}

const dialogShow = () => {
  // 显示相机画面
  state.isCanvas = false
  //获取相机所需信息
  nextTick(() => {
    //获取video节点
    video.value = document.getElementById('video')
    // 获取画布节点
    canvas.value = document.getElementById('canvas')
    // 图片展示
    photo.value = document.getElementById('photo')
    // 为画布指定绘画为2d类型
    if (canvas.value) {
      ctx.value = canvas.value.getContext('2d')
    }
    //获取摄像头权限
    getCompetence()
  })
}

//关闭弹窗
const close = () => {
  dialogVisible.value = false
}

//点击拍照截图画面
const takePhone = () => {
  canvas.value.width = width
  canvas.value.height = height
  state.isCanvas = true
  ctx.value.drawImage(video.value, 0, 0, width, height)
  state.dataurl = canvas.value.toDataURL('image/jpeg')
  state.preViewVisible = true
// 这里获取到了拍照的base64
  photo.value.setAttribute('src', state.dataurl)
  emit('get-photo', state.dataurl)
  close()
}

// 调用摄像头权限
const getCompetence = async () => {
  loading.value = ElLoading.service({
    lock: true,
    text: '正在获取摄像头权限...',
    target: document.querySelector('#loading') as any
  })
  //必须在model中render后才可获取到dom节点,直接获取无法获取到model中的dom节点
  if (navigator.mediaDevices === undefined) {
    let navigator: any
    navigator.menavigatordiaDevices = {}
  }
  // 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
  // 使用getUserMedia,因为它会覆盖现有的属性。
  // 这里,如果缺少getUserMedia属性,就添加它。
  if (navigator.mediaDevices.getUserMedia === undefined) {
    navigator.mediaDevices.getUserMedia = function (constraints: any) {
      // 首先获取现存的getUserMedia(如果存在)
      let navigator: any
      let getUserMedia =
        navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia
      // 保持接口一致
      if (!getUserMedia) {
        return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
      }
      // 否则,使用Promise将调用包装到旧的navigator.getUserMedia
      return new Promise(function (resolve, reject) {
        getUserMedia.call(navigator, constraints, resolve, reject)
      })
    }
  }

  var constraints = {
    audio: false,
    video: {
      width: 2592,
      height: 1944
    }
  }

  navigator.mediaDevices
    .getUserMedia(constraints)
    .then(function () {
      // 获取摄像头设备信息
      getVideo(loading.value)
    })
    .catch(function (err) {
      ElMessage.error('打开摄像头失败请检查浏览器设置或域名是否安全!')
      setTimeout(() => {
        loading.value.close()
        close()
      }, 1000)
    })
}

// 获取摄像头设备信息
const getVideo = (loading: any) => {
  videoArr.list = []
  if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
    navigator.mediaDevices.enumerateDevices().then(function (devices) {
      for (var j = 0; j < devices.length; j++) {
        if (devices[j].kind == 'videoinput') {
          videoArr.list.push({
            label: devices[j].label,
            id: devices[j].deviceId
          })
        }
      }
      let labelRight = videoArr.list.findIndex((item) => {
        return item.label.indexOf('HD USB Camera') == 0
      })
      if (labelRight != -1) {
        let labelId = videoArr.list.find((item) => {
          return item.label.indexOf('HD USB Camera') == 0
        })?.id
        cameraId.value = labelId
        if (cameraId.value) {
          //调用获取到的摄像头权限
          TakeP(loading)
        }
      } else {
        setTimeout(() => {
          close()
          loading.close()
          ElMessage.error('您未链接正确设备,请检查!')
        }, 10000)
      }
    })
  }
}

//显示摄像画面
const TakeP = (loading: any) => {
  var constraints = {
    audio: false,
    video: {
      width: 2592,
      height: 1944,
      deviceId: cameraId.value
    }
  }
  navigator.mediaDevices
    .getUserMedia(constraints)
    .then((mediaStream) => {
      video.value.srcObject = mediaStream
      video.value.play()
      setTimeout(() => {
        loading.close()
      }, 30)
    })
    .catch((err) => {
      setTimeout(() => {
        loading.close()
      }, 30)
    })
  video.value.addEventListener(
    'canplay',
    (ev) => {
      if (!streaming.value) {
        height = video.value.videoHeight / (video.value.videoWidth / width)
        if (isNaN(height)) {
          height = width / (4 / 3)
        }
        console.log('width:' + width)
        console.log('height:' + height)
        console.log('v-width:' + video.value.videoWidth)
        console.log('v-height:' + video.value.videoHeight)
        video.value.setAttribute('width', width)
        video.value.setAttribute('height', height)
        canvas.value.setAttribute('width', width)
        canvas.value.setAttribute('height', width)
        streaming.value = true
      }
    },
    false
  )
}

//重拍
const takeAgain = () => {
  loading.value = ElLoading.service({
    lock: true,
    text: '正在获取摄像头画面...',
    target: document.querySelector('#loading') as any
  })
  state.isCanvas = false
  TakeP(loading.value)
}

defineExpose({
  show,
  loading,
  takeAgain,
  close,
  TakeP
})
</script>
要实现Vue 3与德卡T10身份证读卡器的对接,可按以下步骤进行: ### 1. 准备开发环境 - 下载德卡T10桌面读卡器开发包,该开发包提供了硬件接口文档、驱动程序、示例代码及辅助工具,有助于快速上手并实现与读卡器的交互,开发包项目地址为:https://gitcode.com/Universal-Tool/3a26b [^2]。 - 确保计算机系统安装了德卡T10读卡器的驱动程序,开发包的兼容性强,适用于多种计算机系统。 ### 2. 创建Vue 3项目 使用Vue CLI或Vite创建一个新的Vue 3项目: ```bash # 使用Vite创建项目 npm init vite@latest my-vue3-project -- --template vue cd my-vue3-project npm install ``` ### 3. 调用DLL动态链接库 德卡T10读卡器项目源码包含用C#语言编写的程序,通过调用DLL动态链接库与读卡器通信以实现卡片数据的读取。在Vue 3项目中,由于无法直接调用DLL,可借助Node.js来实现。 - 安装`ffi-napi`库,它可用于在Node.js中调用动态链接库: ```bash npm install ffi-napi ``` - 创建一个Node.js脚本,在脚本中使用`ffi-napi`调用DLL中的函数。以下是示例代码: ```javascript const ffi = require(&#39;ffi-napi&#39;); // 加载DLL const dll = ffi.Library(&#39;path/to/your/dll&#39;, { // 定义DLL中的函数 &#39;FunctionName&#39;: [&#39;returnType&#39;, [&#39;parameterType1&#39;, &#39;parameterType2&#39;]] }); // 调用DLL函数 const result = dll.FunctionName(arg1, arg2); console.log(result); ``` 将`&#39;path/to/your/dll&#39;`替换为实际的DLL文件路径,`&#39;FunctionName&#39;`替换为DLL中要调用的函数名,`&#39;returnType&#39;``&#39;parameterType1&#39;`等替换为实际的返回类型参数类型。 ### 4. 在Vue 3组件中调用Node.js脚本 可使用`child_process`模块在Vue 3组件中调用Node.js脚本: ```vue <template> <div> <button @click="readCard">读取卡片</button> <p>{{ cardData }}</p> </div> </template> <script setup> import { ref } from &#39;vue&#39;; import { exec } from &#39;child_process&#39;; const cardData = ref(&#39;&#39;); const readCard = () => { exec(&#39;node path/to/your/node/script.js&#39;, (error, stdout, stderr) => { if (error) { console.error(`执行脚本时出错: ${error}`); return; } cardData.value = stdout; }); }; </script> ``` 将`&#39;path/to/your/node/script.js&#39;`替换为实际的Node.js脚本路径。 ### 5. 实现关键步骤 实现初始化读卡器、搜索卡片、读取数据、解析数据及异常处理等关键步骤,这些步骤在德卡T10读卡器项目源码中有体现。在调用DLL函数时,需根据DLL的文档接口说明来正确调用相应的函数以完成这些步骤 [^1]。 ### 6. 数据安全加密 项目涵盖了数据安全加密措施,确保个人信息安全。在读取处理卡片数据时,要遵循这些安全措施,保障数据的安全性 [^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值