開箱即用的前端圖片壓縮方案
前端實現圖片壓縮的背景
我們都知道在 “寸土寸金” 的互聯網時代, 速度是第一競爭力, 雖然我們的 5G 發展已經搖搖領先, 但是也經不住用戶在一個網頁裏傳很多 “巨無霸” 圖片, 最終導致的結果就是頁面 “龜速” 打開......
那麼作爲技術人, 當然也有一堆的解決方案, 比如:
-
壓縮圖片再上傳
-
將圖片上傳到圖牀, 利用圖牀壓縮能力和 CDN 節點就近分發
-
圖片流式加載
-
圖片懶加載 / 預加載
當然聰明的小夥伴也會將上面的方案組合, 設計更優秀的圖片 “提速” 方案.
今天不會和大家把所有方案都介紹一遍, 因爲網上也有很多實踐, 接下來會從前端技術提升的角度, 分享一下如何用原生 javascript, 實現從圖片上傳到圖片自定義壓縮的完整方案. 大家可以把文章中介紹的方案直接用於自己的實際開發中, 或者基於它設計更棒的圖片壓縮方案.
實現圖片壓縮的方案
前端實現圖片壓縮無非就是在用戶上傳圖片文件後, 將file
轉換成image對象
, 然後再利用canvas
及其 api
將圖片壓縮成指定體積. 如下流程:
代碼實現
首先我們先實現將file
轉換成image對象
, 這裏我們用到了FileReader
API, 代碼如下:
// 壓縮前將file轉換成img對象
function readImg(file: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)
}
})
}
這裏使用 promise
來設計生成圖片數據的方法, 接下來我們看看核心的圖片壓縮源碼:
/**
* 壓縮圖片
* @param img 被壓縮的img對象
* @param type 壓縮後轉換的文件類型
* @param mx 觸發壓縮的圖片最大寬度限制
* @param mh 觸發壓縮的圖片最大高度限制
* @param quality 圖片質量
*/
function compressImg(img: any, type:string, mx: number, mh: number, quality:number = 1) {
return new Promise((resolve, reject) => {
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
context?.clearRect(0, 0, targetWidth, targetHeight)
// 圖片繪製
context?.drawImage(img, 0, 0, targetWidth, targetHeight)
canvas.toBlob(function(blob) {
resolve(blob)
}, type || 'image/png', quality)
})
}
這裏通過控制 canvas
的寬高, 以及對 canvas
的 toBlob
設置參數, 來實現自定義的圖片壓縮.
如果大家對代碼又不理解的地方, 也可以在文末發表問題, 我會做對應的解答.
更多前端提效方案
-
xijs 一款面向複雜業務場景的 javascript 工具庫
-
react-slider-vertify 基於 react 實現的滑動驗證碼組件
-
react-cropper-pro 支持圖片上傳 + 裁切 + 壓縮的組件
-
h5-dooring 在線 H5 頁面製作工具
-
v6.Dooring 可視化大屏搭建平臺
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/gU8h55POpyyN1UyOH3iGxw