Vue3中调用摄像头并拍照,把base64转换为file文件,在转换为文件上传要的格式

该Vue组件展示了如何利用navigator.mediaDevices.getUserMedia获取摄像头实时画面,拍照后将canvas转换为图片数据URL,再通过dataURLtoFile函数转为File对象,最后用FormData上传至服务器。
摘要由CSDN通过智能技术生成
export function dataURLtoFile(dataurl, filename) {
  //将base64转换为文件
  var arr = dataurl.split(","),
    mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], filename, {
    type: mime,
  });
}
<template>
    <n-card style="width: 660px" title="请对准摄像头" :bordered="false" size="huge" role="dialog" aria-modal="true">
        <div flex>
            <div text-center class="text-[#8dc6e5]">
                <div mb2>摄像头实时画面</div>
                <div w40 h50>
                    <dv-border-box-8 p10px>
                        <video ref="video" autoplay wh-full></video>
                    </dv-border-box-8>
                </div>
            </div>
            <div ml15 mr15 mt15>
                <n-button type="tertiary" w20 @click="takePhoto">
                    拍照
                </n-button>
                <n-button type="info" mt2 w20 @click="submitData">
                    保存
                </n-button>
            </div>
            <div text-center class="text-[#8dc6e5]">
                <div mb2>拍照图片</div>
                <div w40 h50>
                    <dv-border-box-8 p10px>
                        <img ref="photo" style="display: none" wh-full>
                    </dv-border-box-8>
                </div>
            </div>
        </div>
    </n-card>
</template>

<script setup>
import { onMounted } from "vue"
import api from "@/api/camera/index"
import {dataURLtoFile} from "@/utils/common/common"

const video = ref(null)

const photo = ref(null)

const submitData = () => {         
        clearVideo()
        uploadImg()
}

const takePhoto = () => {
    const canvas = document.createElement('canvas');
    canvas.width = video.value.videoWidth;
    canvas.height = video.value.videoHeight;
    // 将摄像头捕捉到的图像绘制到canvas上
    canvas.getContext('2d').drawImage(video.value, 0, 0, canvas.width, canvas.height);
    // 将canvas转换为图片
    photo.value.src = canvas.toDataURL('image/jpeg');
    // 显示图片
    photo.value.style.display = 'block';
}

const clearVideo = () => {
    // 关闭摄像头
    const stream = video.value.srcObject;
      const tracks = stream.getTracks();
      tracks.forEach(track => {
        track.stop();
      });
      video.value.srcObject = null;
}

// 重点
const uploadImg = async () => {
    var formData = new FormData()
    
    // 把file传给formData
    const photoFile  = dataURLtoFile(photo.value.src,'img')
    formData.append("file", photoFile );
    const res = await api.getPosts(formData)
    console.log("🚀 ~ file: index.vue:98 ~ uploadImg ~ res:", res)
}


onMounted(() => {
    // 调用摄像头
    navigator.mediaDevices.getUserMedia({ video: true })
        .then(stream => {
            // 将摄像头捕捉到的视频流绑定到video元素上
            video.value.srcObject = stream;
        })
        .catch(error => {
            console.error(error);
        });
})


</script>

<style></style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值