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