前端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.png'
link.target = '_blank'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}