基於canvas實現圖片壓縮
阿新 • • 發佈:2019-01-06
用法:
compressImg(target.files[0], 2).then(base64 => {
console.log(base64)
// 在這裡實現壓縮後的上傳操作
// ...
}).catch(err => { // 壓縮異常
Indicator.close()
_this.$toast(err)
})
詳細見程式碼註釋
/** * 圖片壓縮 * @param file 圖片原檔案【必傳】 * @param maxDefaultSize 壓縮後的最大值限制,預設10M * @param quality 壓縮後的質量,取值範圍:(0, 1], 預設值:1 * @param type 壓縮後的檔案字尾名, 預設值:'jpeg' * @returns {Promise<any>} */ export function compressImg (file = null, maxDefaultSize = 10, quality = 1, type = 'jpeg') { let imgQuality = quality > 1 ? 1 : quality <= 0 ? 0.1 : quality // imgQuality取值範圍:(0, 1] let reader = new FileReader() let img = new Image() // 圖片轉base64後的大小 let imgSize = 0 // 選擇的檔案是圖片 if (file.type.indexOf('image') === 0) { reader.readAsDataURL(file) } // 檔案base64化,以便獲知圖片原始尺寸 reader.onload = function (e) { imgSize = e.total img.src = e.target.result } // 建立縮放圖片所需的canvas let canvas = document.createElement('canvas') let context = canvas.getContext('2d') // 返回promise物件 return new Promise((resolve, reject) => { // base64地址圖片載入完畢後 img.onload = (e) => { // 圖片原始尺寸 let originWidth = img.width let originHeight = img.height // 最大尺寸限制和最大圖片佔用空間限制 let maxWidth = 500 let maxHeight = 500 let maxSize = 2 * 1024 * 1024 // 2M // 目標尺寸 let targetWidth = originWidth let targetHeight = originHeight // 圖片尺寸超過500*500最大尺寸的限制,或超過2M限制 if (imgSize > maxSize || originWidth > maxWidth || originHeight > maxHeight) { // 圖片原始寬高比例大於最大寬高比例,按照寬度限定尺寸 if (originWidth / originHeight > maxWidth / maxHeight) { targetWidth = maxWidth targetHeight = Math.round(maxWidth * (originHeight / originWidth)) } else { targetWidth = Math.round(maxHeight * (originWidth / originHeight)) targetHeight = maxHeight } } // 使用canvas對圖片進行縮放壓縮操作 canvas.width = targetWidth canvas.height = targetHeight // 清除畫布 context.clearRect(0, 0, targetWidth, targetHeight) // 圖片壓縮 context.drawImage(img, 0, 0, targetWidth, targetHeight) // canvas轉為base64上傳 let targetType = type ? `image/${type}` : file.type || 'image/jpeg' let base64 = canvas.toDataURL(targetType, imgQuality) let strContent = base64.split('base64,')[1].replace(/=/g, '') let contentLen = strContent.length let base64Size = parseInt(contentLen - (contentLen / 8) * 2) // 壓縮後還大於壓縮後最大值限制 if (base64Size > maxDefaultSize * 1024 * 1024) { let errMsg = '圖片過大,請重新選擇' reject(errMsg) } else { resolve(base64) } // canvas轉為blob上傳 // canvas.toBlob((blob) => { // console.log('canvas轉為blob上傳---', blob) // resolve(blob) // }, `image/${type}` || file.type || 'image/jpeg') } img.onerror = () => { let errMsg = '圖片載入失敗' reject(errMsg) } }) }