当前位置: 首页 > article >正文

结合华为云实现人证核验

结合华为云实现人核核验
<template>
  <view class="content">
	<!-- 身份证正面 -->
	<view class="photo-container" v-if="photo1" style="margin-bottom: 30px;">
	  <image :src="photo1" mode="aspectFit" class="photo"></image>
	  <view class="close-button" @click="clearPhoto(1)">×</view>
	</view>
	<view v-else>
	  <navigator class="buttons" url="../camera/idcard/idcard?dotype=idcardface">
		<button type="primary">身份证正面</button>
	  </navigator>
	</view>
	
	
	<!-- 人脸拍照 -->
	<view class="photo-container" v-if="photo2">
	  <image :src="photo2" mode="aspectFit" class="photo"></image>
	  <view class="close-button" @click="clearPhoto(2)">×</view>
	</view>
	<view v-else>
	  <navigator class="buttons" url="../camera/idphoto/idphoto">
		<button type="primary">人脸拍照</button>
	  </navigator>
	</view>
    <button @click="submitPhotos()" type="primary">人证核验</button>
	<canvas id="canvas-clipper" canvas-id="canvas-clipper" type="2d" :style="{ width: state.canvasSiz.width + 'px', height: state.canvasSiz.height + 'px', position: 'absolute', left: '-500000px', top: '-500000px' }" />
	
  </view> 
</template>
<script setup>
import { ref, onMounted, reactive } from 'vue';
import { pathToBase64, base64ToPath } from 'image-tools';
import { ivs } from '../../api/ivsStandard';
import { onLoad } from '@dcloudio/uni-app';
const photo1 = ref('');
const photo2 = ref('');
const takePhoto = async (index) => {
  try {
    const res = await new Promise((resolve, reject) => {
      uni.chooseImage({
        count: 1,
        sizeType: ['original', 'compressed'],
        sourceType: ['camera','album'],
        success: resolve,
        fail: reject
      });
    });

    if (res.tempFilePaths.length > 0) {
      const tempFilePath = res.tempFilePaths[0];
      const base64String = await convertToBase64(tempFilePath);
      if (index === 1) {
        photo1.value = base64String;
      } else if (index === 2) {
        photo2.value = base64String;
      }
    }
  } catch (error) {
  }
};


const convertToBase64 = (filePath) => {
  return pathToBase64(filePath)
    .then(base64 => {
      return base64;
    })
    .catch(error => {
      console.error('转换失败:', error);
      throw error; // 重新抛出错误以便在调用者中捕获
    });
};

// 人证核身标准版(三要素)
const submitPhotos = () => {
		if (!photo1.value || !photo2.value) {
			uni.showToast({ title: '请拍摄两张照片' });
			return;
		}
		const prefix = "data:image/jpeg;base64,";
		ivs(photo1.value.substring(prefix.length),photo2.value.substring(prefix.length));
};


const clearPhoto = (index) => {
  if (index === 1) {
    photo1.value = '';
  } else if (index === 2) {
    photo2.value = '';
  }
};


const state = reactive({
  windowWidth: '',
  windowHeight: '',
  canvasSiz: {
    width: 188,
    height: 273
  }
});

const init = () => {
  uni.getSystemInfo({
    success: (res) => {
      state.windowWidth = res.windowWidth;
      state.windowHeight = res.windowHeight;
    }
  });
};

const setImage = (e) => {
  if (e.dotype === 'idphoto') {
    zjzClipper(e.path,e.index);
  } else if (e.dotype === 'watermark') {
    watermark(e.path);
  } else {
    savePhoto(e.path,e.index);
  }
};

const zjzClipper = (path,index) => {
  uni.getImageInfo({
    src: path,
    success: (image) => {
      state.canvasSiz.width = 188;
      state.canvasSiz.height = 273;

      let ctx = uni.createCanvasContext('canvas-clipper');

      ctx.drawImage(
        path,
        parseInt(0.15 * image.width),
        parseInt(0.17 * image.height),
        parseInt(0.69 * image.width),
        parseInt(0.65 * image.height),
        0,
        0,
        188,
        273
      );

      ctx.draw(false, () => {
        uni.canvasToTempFilePath(
          {
            destWidth: 188,
            destHeight: 273,
            canvasId: 'canvas-clipper',
            fileType: 'jpg',
            success: (res) => {
              savePhoto(res.tempFilePath,index);
            }
          },
          this
        );
      });
    }
  });
};

const watermark = (path) => {
  uni.getImageInfo({
    src: path,
    success: (image) => {
      state.canvasSiz.width = image.width;
      state.canvasSiz.height = image.height;

      setTimeout(() => {
        let ctx = uni.createCanvasContext('canvas-clipper');

        ctx.drawImage(
          path,
          0,
          0,
          image.width,
          image.height
        );

        ctx.setFillStyle('white');
        ctx.setFontSize(40);
        ctx.fillText('live-camera', 20, 100);

        const now = new Date();
        const time = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()} ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
        ctx.setFontSize(30);
        ctx.fillText(time, 20, 140);

        ctx.draw(false, () => {
          uni.canvasToTempFilePath(
            {
              destWidth: image.width,
              destHeight: image.height,
              canvasId: 'canvas-clipper',
              fileType: 'jpg',
              success: (res) => {
                savePhoto(res.tempFilePath);
              }
            },
            this
          );
        });
      }, 500);
    }
  });
};

const savePhoto = async(path,index) => {
  if (path) {
    const base64String = await convertToBase64(path);
    if (index === 1) {
      photo1.value = base64String;
    } else if (index === 2) {
      photo2.value = base64String;
    }
  }
  
};

onLoad(() => {
  init();
});







defineExpose({setImage});
</script>
<style scoped>
.content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.photo-container {
  position: relative;
  width: 200px;
  height: 200px;
}

.photo {
  width: 100%;
  height: 100%;
}

.close-button {
  position: absolute;
  top: 0;
  right: 0;
  background-color: rgba(255, 0, 0, 0.7);
  color: white;
  font-size: 10px;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  cursor: pointer;
}

button {
  margin: 10px;
}
</style>

http://www.kler.cn/a/460087.html

相关文章:

  • OpenLinkSaas使用手册-待办事项和通知中心
  • python实现自动登录12306抢票 -- selenium
  • wangEditor/editor自定义粘贴后续
  • 设计模式の状态策略责任链模式
  • Vue3 + ElementPlus动态合并数据相同的单元格(超级详细版)
  • Java开发-后端请求成功,前端显示失败
  • C++ 设计模式:抽象工厂(Abstract Factory)
  • pyqt5 设计pdf 和word文件互相转换小程序
  • 二、SQL语言,《数据库系统概念》,原书第7版
  • 【Redis】万字整理 Redis 非关系型数据库的安装与操作
  • Android笔试面试题AI答之Android基础(4)
  • elementui的默认样式修改
  • 备战春招 | 数字IC FPGA笔试题
  • 【从零开始入门unity游戏开发之——C#篇32】C#其他不常用的泛型数据结构类、顺序存储和链式存储
  • Python 爬虫中的反爬策略及详细应对方法
  • 【LLM】Langflow 的简单使用
  • SQL实现新年倒计时功能
  • golang标准库SSH操作示例
  • PHP语言laravel框架中基于Redis的异步队列使用实践与原理
  • 【每日学点鸿蒙知识】中间产物版本号问题、Toast应用外不生效、Dialog键盘问题、WebView cookie、本地缓存
  • 如何判断服务器是否被网络攻击?
  • 【C++】九九乘法表编程题详解与多角度对比分析
  • 整合版canal ha搭建--基于1.1.4版本
  • CSS系列(39)-- Shapes详解
  • 服务器反应慢,秒杀设计
  • 实验七 函数2