input選擇圖片後對圖片轉換和壓縮處理

咱們經常在選擇完圖片後須要對圖片進行處理,包括格式轉換以及壓縮等,最近遇到此場景,故整理彙總爲以下:javascript

// 圖片處理, 輸入文件,輸出base64和文件
  dealImg(file: File, callback: any) {
    this.fileToBase64(file, (base64: any) => {
      this.compressImg(base64, (compressBase64: any) => {
        callback({
          base64,
          file: this.base64ToFile(compressBase64, file.name)
        });
      });
    });
  }

  // 獲取圖片用於展現,輸入文件,輸出base64
  fileToBase64(file: File, callback: any) {
    const fr = new FileReader();
    fr.onload = (evt: any) => {
      callback(evt.target.result);
    };
    fr.readAsDataURL(file);
  }

  // 圖片壓縮,輸入base64,輸出base64
  compressImg(base64: any, callback: any, w: number = 1000) {
    const newImage = new Image();
    const quality = 0.8;    // 壓縮係數0-1之間
    newImage.src = base64;
    newImage.setAttribute("crossOrigin", 'Anonymous');    // url爲外域時須要
    let imgWidth;
    let imgHeight;
    newImage.onload = function() {
      // @ts-ignore
      imgWidth = this.width;
      // @ts-ignore
      imgHeight = this.height;
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d") as any;
      if (Math.max(imgWidth, imgHeight) > w) {
        if (imgWidth > imgHeight) {
          canvas.width = w;
          canvas.height = w * imgHeight / imgWidth;
        } else {
          canvas.height = w;
          canvas.width = w * imgWidth / imgHeight;
        }
      } else {
        canvas.width = imgWidth;
        canvas.height = imgHeight;
      }
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      // @ts-ignore
      ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
      const newBase64 = canvas.toDataURL("image/jpeg", quality);
      callback(newBase64); // 必須經過回調函數返回,不然沒法及時拿到該值
    }
  }
  
  // 將base64轉換爲文件格式
  base64ToFile(base64: string, fileName: string): File {
    const arr = base64.split(',');
    // @ts-ignore
    const mime = arr[0].match(/:(.*?);/)[1];
    const bytes = atob(arr[1]);
    const bytesLength = bytes.length;
    const u8arr = new Uint8Array(bytesLength);
    for (let i = 0; i < bytes.length; i++) {
      u8arr[i] = bytes.charCodeAt(i);
    }
    const blob = new Blob([u8arr], { type: mime })
    return new File([blob], fileName, {
      type: 'image/jpeg'
    });
  }

調用方式以下:java

// 單個文件處理,若是有有多文件能夠遍歷處理
onSingleFileChange(e: any) {
    const files = e.target.files;
    this.dealImg(files[0], (result: any) => {
      console.log(result);
    });
  }
相關文章
相關標籤/搜索