vue3实现上传图片并压缩


vue3实现原生上传图片并压缩为base64后,转成二进制文件,实现预览

<template>

<template>
  <div @click="chooseImg">上传</div>
  <div v-for="(item, index) in imgUrls" :key="index" >
     <img :src="item.src" />
  </div>
</template>

script

interface STATE {
  imgUrls: Array<{
    id: string;
    src: string;
  }>;
}
export default {
  name: "Index",
  setup() {
    const state = reactive<STATE>({
      imgUrls: [], // 上传的图片展示列表
    });
    /** 选择图片 */
    const chooseImg = () => {
      let inputUploadObj: any = document.createElement("input");
      inputUploadObj.setAttribute("id", "input_upload_ID");
      inputUploadObj.setAttribute("type", "file");
      // 添加这个属性,就可以唤起相机的功能
      // inputUploadObj.setAttribute("capture", "user"); // 后置摄像头:camcorder 前置摄像头:user
      // 这里如果不加属性 accept 是 "image/*" 或者 "video/*",就默认打开摄像头,既可以拍照也可以录像
      inputUploadObj.setAttribute("accept", "image/*");
      inputUploadObj.setAttribute("style", "visibility:hidden");
      // 这里将创建的隐式input控件拼接到body的最后面,会增加页面的长度,所以要在适当的时候,移除掉这个隐式创建的input控件
      document.body.appendChild(inputUploadObj);
      // 这里是模拟点击了input控件
      inputUploadObj.click();
      // console.log(inputUploadObj.files[0])
      inputUploadObj.onchange = () => {
        uploadImg(inputUploadObj.files[0]);
      }
    };

    // 将文件转成img对象
    const readImg = function (file) {
      return new Promise((resolve, reject) => {
        const img = new Image();
        const reader = new FileReader();
        reader.onload = function (e: any) {
          img.src = e.target.result;
        };
        reader.onerror = function (e) {
          reject(e);
        };
        reader.readAsDataURL(file);
        img.onload = function () {
          resolve(img);
        };
        img.onerror = function (e) {
          reject(e);
        };
      });
    };

    /**
     * 压缩图片
     *@param img 被压缩的img对象
     * @param type 压缩后转换的文件类型
     * @param mx 触发压缩的图片最大宽度限制
     * @param mh 触发压缩的图片最大高度限制
     */
    const compressImg = (img, type, mx, mh): any => {
      const canvas = document.createElement("canvas");
      const context = canvas.getContext("2d");
      const { width: originWidth, height: originHeight } = img;
      // 最大尺寸限制
      const maxWidth = mx;
      const maxHeight = mh;
      // 目标尺寸
      let targetWidth = originWidth;
      let targetHeight = originHeight;
      if (originWidth > maxWidth || originHeight > maxHeight) {
        if (originWidth / originHeight > 1) {
          // 宽图片
          targetWidth = maxWidth;
          targetHeight = Math.round(maxWidth * (originHeight / originWidth));
        } else {
          // 高图片
          targetHeight = maxHeight;
          targetWidth = Math.round(maxHeight * (originWidth / originHeight));
        }
      }
      canvas.width = targetWidth;
      canvas.height = targetHeight;
      if (context) {
        context.clearRect(0, 0, targetWidth, targetHeight);
        // 图片绘制
        context.drawImage(img, 0, 0, targetWidth, targetHeight);
      }
      return canvas.toDataURL(type || "image/jpeg", 0.5);
    };

    // base64 转二进制
    const 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,
      });
    }
    // 随机数
    const randomNum = ()=>{
      var Num="";
      for(var i=0;i<13;i++)
      {
        Num+=Math.floor(Math.random()*10);
      }
      return Num
    }
  }
  
  // 上传图片
  const uploadImg = async (file) => {
    const img = await readImg(file);
    const blob = compressImg(img, file.type, 1000, 1000);
    state.imgUrls.push({
       id: randomNum(),
       src: blob,
    });
    let formdata = new FormData();
    formdata.append("file", dataURLtoFile(blob,"file-"+randomNum()));
    // 上传图片接口调用
  }
  return {
    ...toRefs(state),
    chooseImg
  }
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM