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