天天看點

#yyds幹貨盤點#前端圖檔壓縮

FileReader

​FileReader​

​​ 對象允許 Web 應用程式異步讀取存儲在使用者計算機上的檔案(或原始資料緩沖區)的内容,使用 ​

​File​

​​ 或 ​

​Blob​

​ 對象指定要讀取的檔案或資料。

其中 File 對象可以是來自使用者在一個​

​<input>​

​元素上選擇檔案後傳回的​

​FileList​

​對象,也可以來自拖放操作生成的 ​

​DataTransfer​

​對象,還可以是來自在一個​

​HTMLCanvasElement​

​上執行​

​mozGetAsFile()​

​方法後傳回結果。

重要提示:​

​ FileReader​

​​ 僅用于以安全的方式從使用者(遠端)系統讀取檔案内容 它不能用于從檔案系統中按路徑名簡單地讀取檔案。要在 ​

​JavaScript​

​​ 中按路徑名讀取檔案,應使用标準 ​

​Ajax​

​​ 解決方案進行伺服器端檔案讀取,如果讀取跨域,則使用 ​

​CORS​

​ 權限。

構造函數

  • ​FileReader()​

    ​​ 傳回一個新構造的​

    ​FileReader​

    ​。

屬性

  • ​FileReader.error​

    ​ 隻讀

    一個

    DOMException

    ,表示在讀取檔案時發生的錯誤 。
  • ​FileReader.readyState​

    ​ 隻讀

    表示

    FileReader

    狀态的數字。取值如下:
常量名 描述

​EMPTY​

​0​

還沒有加載任何資料。

​LOADING​

​1​

資料正在被加載。

​DONE​

​2​

已完成全部的讀取請求。
  • ​FileReader.result​

    ​​ 隻讀

    檔案的内容。該屬性僅在讀取操作完成後才有效,資料的格式取決于使用哪個方法來啟動讀取操作。

事件處理

  • ​FileReader.onabort​

    ​處理

    abort (en-US)

    事件。該事件在讀取操作被中斷時觸發。
  • ​FileReader.onerror​

    ​處理

    error (en-US)

    事件。該事件在讀取操作發生錯誤時觸發。
  • ​FileReader.onload​

    ​處理

    load (en-US)

    事件。該事件在讀取操作完成時觸發。
  • ​FileReader.onloadstart​

    ​處理

    loadstart (en-US)

    事件。該事件在讀取操作開始時觸發。
  • ​FileReader.onloadend​

    ​處理

    loadend (en-US)

    事件。該事件在讀取操作結束時(要麼成功,要麼失敗)觸發。
  • ​FileReader.onprogress​

    ​處理

    progress (en-US)

    事件。該事件在讀取

    Blob

    時觸發。

備注:  因為 ​

​FileReader​

​​ 繼承自​

​EventTarget​

​​,是以所有這些事件也可以通過​

​addEventListener​

​方法使用。

方法

  • ​FileReader.abort()​

    ​中止讀取操作。在傳回時,

    readyState

    屬性為

    DONE

  • ​FileReader.readAsArrayBuffer()​

    ​開始讀取指定的

    Blob

    中的内容,一旦完成,result 屬性中儲存的将是被讀取檔案的 

    ArrayBuffer

    資料對象。
  • ​FileReader.readAsBinaryString()​

    ​ 非标準

    開始讀取指定的

    Blob

    中的内容。一旦完成,

    result

    屬性中将包含所讀取檔案的原始二進制資料。
  • FileReader.readAsDataURL()

    開始讀取指定的

    Blob

    中的内容。一旦完成,

    result

    屬性中将包含一個

    data:

     URL 格式的 Base64 字元串以表示所讀取檔案的内容。
  • ​FileReader.readAsText()​

    ​​開始讀取指定的​

    ​Blob​

    ​​中的内容。一旦完成,​

    ​result​

    ​屬性中将包含一個字元串以表示所讀取的檔案内容。

封裝讀取檔案方法

const fileToDataURL = (file: Blob): Promise<any> => {
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onloadend = (e) => resolve((e.target as FileReader).result)
    reader.readAsDataURL(file)
  })
}      

然後将檔案流轉成圖檔.

Image()

**​

​Image()​

​​**函數将會建立一個新的​

​HTMLImageElement​

​執行個體。

它的功能等價于 ​

​document.createElement('img')​

文法

Image(width, height)      

參數

  • width

    圖檔的寬度 (即

    width

     屬性).
  • height

    圖檔的高度 (即​

    ​height​

    ​ 屬性).

封裝将檔案流轉成圖檔方法

const dataURLToImage = (dataURL: string): Promise<HTMLImageElement> => {
  return new Promise((resolve) => {
    const img = new Image()
    img.onload = () => resolve(img)
    img.src = dataURL
  })
}      

關于canvas封裝

const canvastoFile = (canvas: HTMLCanvasElement, type: string, quality: number): Promise<Blob | null> => {
  return new Promise((resolve) => canvas.toBlob((blob) => resolve(blob), type, quality))
}      

最後就是整合成一個異步的圖檔壓縮方法

const fileToDataURL = (file: Blob): Promise<any> => {
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onloadend = (e) => resolve((e.target as FileReader).result)
    reader.readAsDataURL(file)
  })
}
const dataURLToImage = (dataURL: string): Promise<HTMLImageElement> => {
  return new Promise((resolve) => {
    const img = new Image()
    img.onload = () => resolve(img)
    img.src = dataURL
  })
}
const canvastoFile = (canvas: HTMLCanvasElement, type: string, quality: number): Promise<Blob | null> => {
  return new Promise((resolve) => canvas.toBlob((blob) => resolve(blob), type, quality))
}
/**
 * 圖檔壓縮方法
 * @param {Object}  file 圖檔檔案
 * @param {String} type 想壓縮成的檔案類型
 * @param {Nubmber} quality 壓縮品質參數
 * @returns 壓縮後的新圖檔
 */
export const compressionFile = async(file, type = 'image/jpeg', quality = 0.5) => {
  const fileName = file.name
  const canvas = document.createElement('canvas')
  const context = canvas.getContext('2d') as CanvasRenderingContext2D
  const base64 = await fileToDataURL(file)
  const img = await dataURLToImage(base64)
  canvas.width = img.width
  canvas.height = img.height
  context.clearRect(0, 0, img.width, img.height)
  context.drawImage(img, 0, 0, img.width, img.height)
  const blob = (await canvastoFile(canvas, type, quality)) as Blob // quality:0.5可根據實際情況計算
  const newFile = await new File([blob], fileName, {
    type: type
  })
  return newFile
}