公司最近有需要壓縮上傳圖片功能,查找了些資料并實現了一把。
主要用到的原生組件:FileReader、Canvas、Blob、FormData
邏輯步驟:
FileReader.readAsDataURL將上傳的圖片文件轉為Base64格式
將img繪制到canvas上,canvas.toDataURL壓縮圖片
new Blob將壓縮后的Base64轉為Blob格式
FormData.append將圖片文件數據存入formdata
Code:
this.compressImage(files[0], (file)=>{ console.log(file); const formData = new FormData(); formData.append("file", file, file.name || "上傳圖片.jpeg"); }, $.noop); //壓縮圖片 compressImage = (file, success, error) => { // 圖片小于1M不壓縮 if (file.size < Math.pow(1024, 2)) { return success(file); } const name = file.name; //文件名 const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = (e) => { const src = e.target.result; const img = new Image(); img.src = src; img.onload = (e) => { const w = img.width; const h = img.height; const quality = 0.8; // 默認圖片質量為0.92 //生成canvas const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); // 創建屬性節點 const anw = document.createAttribute("width"); anw.nodeValue = w; const anh = document.createAttribute("height"); anh.nodeValue = h; canvas.setAttributeNode(anw); canvas.setAttributeNode(anh); //鋪底色 PNG轉JPEG時透明區域會變黑色 ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, w, h); ctx.drawImage(img, 0, 0, w, h); // quality值越小,所繪制出的圖像越模糊 const base64 = canvas.toDataURL("image/jpeg", quality); //圖片格式jpeg或webp可以選0-1質量區間 // 返回base64轉blob的值 console.log(`原圖${(src.length/1024).toFixed(2)}kb`, `新圖${(base64.length/1024).toFixed(2)}kb`); //去掉url的頭,并轉換為byte const bytes = window.atob(base64.split(",")[1]); //處理異常,將ascii碼小于0的轉換為大于0 const ab = new ArrayBuffer(bytes.length); const ia = new Uint8Array(ab); for (let i = 0; i < bytes.length; i++) { ia[i] = bytes.charCodeAt(i); } file = new Blob( [ab] , {type : "image/jpeg"}); file.name = name; success(file); } img.onerror = (e) => { error(e); } } reader.onerror = (e) => { error(e); } }
遇到的一些坑:
PNG轉JPEG時PNG格式的透明區域會變黑色,需要先手動鋪底色
toDataURL參數為PNG時不支持傳圖片質量,所以需要寫死image/jpeg或image/webp,具體可以參考toDataURL的api
formData.append第三個參數filename是有瀏覽器兼容性問題的,如果不傳就是filename=blob,后端校驗文件名可能過不去
ajax的contentType和processData需要傳false,這和本文關系不大直接帶過
網上說的ios中canvas繪制圖片大小限制我在iphone6上測試沒遇到,可能和機型或系統有關系,如果有可以在下面留言
結語,壓縮功能比較適合移動端,畢竟PC端帶寬比較好而且不能兼容IE老版本。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89827.html
摘要:圖片文件大小減小后,上傳速度自然會提升,在同樣的并發下,后臺處理的速度也會得到提升,用戶體驗得到提升。 這是一個很簡單的方案。嗯,是真的。 為什么要這么做? 在移動Web蓬勃發展的今天,有太多太多的應用需要讓用戶在移動Web上傳圖片文件了,正因如此,我們有些困難必須去攻克: 低網速下上傳進度緩慢,用戶體驗差 高并發下,后臺處理較大的上傳文件壓力大 或許有更多... 在攻克上面的一些...
摘要:大家好,我是云皓,話不多說,直入正題,獲取上傳文件自行獲取,也可通過的組件來獲取,轉化為文件,壓縮,轉換為文件,上傳。 大家好,我是云皓,話不多說,直入正題 1,獲取input上傳file文件(自行獲取,也可通過vant的upload組件來獲取)2,轉化為base64文件3,壓縮4,轉換為blob文件5,上傳。下面直接上代碼(本代碼段是用用在vue&vantui 里面, 原理都在,可根...
摘要:哈哈主要還是我嫌麻煩四上傳圖片這里的頁面樣式,圖片壓縮和預覽都和上面一樣,這里我主要配置一下的,讓接口能夠成功上傳。如果想讓用戶有更好的體驗,可以對圖片進行一下壓縮和本地預覽。 一、通過Form表單提交上傳 HTML enctype屬性必不可少 上面一種方法通過表單自有屬性進行提交,看似簡單,但是也有其最大的缺點,那就是提交...
摘要:哈哈主要還是我嫌麻煩四上傳圖片這里的頁面樣式,圖片壓縮和預覽都和上面一樣,這里我主要配置一下的,讓接口能夠成功上傳。如果想讓用戶有更好的體驗,可以對圖片進行一下壓縮和本地預覽。 一、通過Form表單提交上傳 HTML enctype屬性必不可少 上面一種方法通過表單自有屬性進行提交,看似簡單,但是也有其最大的缺點,那就是提交...
閱讀 2965·2021-11-23 10:12
閱讀 2690·2021-11-23 09:51
閱讀 2040·2021-11-15 11:37
閱讀 1352·2019-08-30 15:55
閱讀 1965·2019-08-29 15:40
閱讀 1165·2019-08-28 18:30
閱讀 1650·2019-08-28 18:02
閱讀 2640·2019-08-26 12:00