前端JS實現圖片質量壓縮
用戶在選擇圖片文件進行上傳的時候是不會考慮文件的大小的,比如場景:
某用戶只是想更換一下自己的用戶頭像,於是用自己的手機拍了一張照片,上傳到應用中更換用戶頭像,然而現在的手機拍照功能保存的圖片大多都超過3MB,而頭像只是一個佔用空間很小的顯示區域,所以上傳一個很大的圖片會浪費資源和消耗不必要的性能
目的:
- 降低流量的消耗
- 降低http請求性能消耗
- 降低服務器壓力
原文件:
壓縮後的文件:
實現方式採用HTML5 中 Canvas
<input type="file" name="" id="upload" value="" />
window.onload = function () {
const upload = document.getElementById('upload')
upload.onchange = uploadImage
}
// 圖片上傳
function uploadImage(event) {
const file = event.target.files
createImage(file[0], function(img) {
createCanvas(img, 1200)
})
event.target.value = ''
}
// 生成圖片副本
function createImage(file, callback) {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function () {
const img = new Image()
img.src = reader.result
callback(img)
}
}
// 生成畫布
function createCanvas(img, max) {
const cvs = document.createElement('canvas')
const ctx = cvs.getContext('2d')
let width = img.naturalWidth || 400
let height = img.naturalHeight || 400
const ratio = width / height
if (width > max) {
width = max
height = width / ratio
}
cvs.width = width
cvs.height = height
img.onload = function() {
const base64 = compressImage(cvs, ctx, img, width, height, max)
console.log(base64)
}
}
// 圖片質量壓縮
function compressImage(cvs, ctx, img, width, height, max) {
// 繪製圖片
ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, width, height)
const quality = width > max ? 0.5 : width > 600 ? 0.6 : 1
const newImageData = cvs.toDataURL('image/png', quality)
downloadImage(newImageData)
return newImageData
}
// 圖片下載
function downloadImage(newImageData) {
const link = document.createElement('a')
link.href = newImageData
link.download = 'img'
link.target = '_blank'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}