vue3 realizes connecting to the camera to take pictures and uploading them to the picture server

Without further ado, let’s get straight to the code.

<template>
  <!-- 拍照 -->
  <el-form-item label="拍照" prop="avatar">
    <el-button size="small" type="primary" @click="takePhotoHandle">连接摄像头</el-button>
    <video id="videoCamera" :width="videoWidth" :height="videoHeight" autoPlay></video>
    <el-button size="small" type="primary" @click="takePhoto">拍照</el-button>
  </el-form-item>
  <!-- <el-form-item label="预览" prop="avatar">
          <canvas id="canvasCamera" :width="videoWidth" :height="videoHeight"></canvas>
          <el-button size="small" type="primary" :loading="loadin" @click="uploadHandle">上传</el-button>
        </el-form-item> -->
</template>

<script setup name="Customer" lang="ts">
import { ref, onUnmounted } from 'vue';

import { uploadAvatar } from "@/api/system/user";
const { proxy } = getCurrentInstance() as ComponentInternalInstance;





const photoVideo = ref<any>(null)// 拍照框
const photoContext = ref<any>(null)// canvas绘图环境
const photoCancas = ref<any>(null)// 预览框
const videoWidth = ref<any>(306)// 拍照框宽度
const videoHeight = ref<any>(378)// 拍照框高度






//打开摄像头页面
const takePhotoHandle = () => {
  openCamera()
}


const openCamera = async () => {
  photoVideo.value = document.getElementById('videoCamera')
  photoCancas.value = document.getElementById('canvasCamera')
  if (photoCancas.value) {
    photoContext.value = photoCancas.value.getContext('2d')

  }
  try {
    const constraints = {
      audio: false,
      video: {
        width: videoWidth.value,
        height: videoHeight.value
      }
    }
    const stream = await navigator.mediaDevices.getUserMedia(constraints)
    photoVideo.value.srcObject = stream
    photoVideo.value.play()
  } catch (error) {

    proxy?.$modal.msgSuccess('操作成功');
  }
}

//拍照
const takePhoto = () => {
  if (photoContext.value) {
    // 创建一个新的canvas元素
    const canvas = document.createElement('canvas');
    // 设置canvas的宽高与视频流的宽高相同
    canvas.width = videoWidth.value;
    canvas.height = videoHeight.value;
    // 将视频流渲染到canvas上
    const context = canvas.getContext('2d');
    if (context) {
      context.drawImage(photoVideo.value, 0, 0, videoWidth.value, videoHeight.value);
    }

    // 将canvas转换为Blob对象
    canvas.toBlob((blob) => {
      if (blob) {
        // 使用Blob对象创建一个File对象
        const file = new File([blob], 'photo.png', { type: 'image/png' });
        // 在这里可以使用file对象进行进一步处理,比如上传到服务器等
        uploadFile(file);
      }
    }, 'image/png');
  }
};

const uploadFile = async (file: File) => {
  const formData = new FormData();
  formData.append('avatarfile', file);
  try {
    const response = await uploadAvatar(formData);
  } catch (error) {
    // 处理网络请求错误
    console.error('网络请求错误', error);
  }
};




onUnmounted(() => {
  if (photoVideo.value && photoVideo.value.srcObject) {
    // 停止视频流
    photoVideo.value.srcObject.getTracks()[0].stop();
  }
})

</script>



Guess you like

Origin blog.csdn.net/qq_40609490/article/details/133297070