天天看点

js 压缩html 图片上传,js canvas 前端实现修改图片尺寸压缩图片大小

函数1:读取图片信息(主要是原使图片宽高)

readImg(file) {

return new Promise((resolve, reject) => {

const img = new Image()

const reader = new FileReader()

reader.onload = function(e) {

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)

}

})

}

函数2:修改图片尺寸(如原图宽高尺寸2000*3000,现在手机拍照像素都很高,照片都在2-5兆,甚至更多大,此时我们将图片宽高尺寸修改到1000*1500,再保存图片,那图片大小肯定就小了)

关于canvas.toBlob(callback, type, encoderOptions);

官方描述:

js 压缩html 图片上传,js canvas 前端实现修改图片尺寸压缩图片大小

compressImg(img, type, mx, mh) {

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

// 只有宽高都超标时才按窄边压缩 (可以按自己需求修改判断条件,如果在调用前就判断了,那这里就不用判断 originWidth > maxWidth && originHeight > maxHeight,也可以改成 || 条件,看自己需求)

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)

// 转成blob, canvas toBlob函数有3个参数,第三个参数官方描述:Number类型,值在0与1之间,当请求图片格式为image/jpeg或者image/webp时用来指定图片展示质量。如果这个参数的值不在指定类型与范围之内,则使用默认值,其余参数将被忽略。

// 简单点说就是修改图片展示质量,如果设置成0.1,那图片质量会压缩的很差,一般在0.8以上可以保证图片在肉眼识别范围不失真,如果对图片质量有要修,只想修改图片宽高尺寸,那建议使用1,默认是0.92,会压缩一点点

canvas.toBlob(function(blob) {

resolve(blob)

}, type || 'image/jpeg')

})

}

函数使用,例如我是在React中使用的,这里需要用到 async 和 await 关键词

async fileChange () {

console.log(this.fileInput)

// ref获取文件对象

var file = this.fileInput.files[0]

console.log(file.size) // 测试打印原文件大小

const formData = new FormData()

const maxWidth = 1000 // 设置目标图片最大宽

const maxHeight = 1000 // 设置目标图片最大高

const img = await this.readImg(file)

const { width: originWidth, height: originHeight } = img

// 宽高都超标,则压缩窄边,否则直接用上传的图片(这里是我业务需求的条件判断,可以按自己需求修改)

if (originWidth > maxWidth && originHeight > maxHeight) {

const blob = await this.compressImg(img, file.type, maxWidth, maxHeight)

formData.append('localImage', blob)

console.log('blob.size', blob.size) // 测试打印压缩后的大小

} else {

formData.append('localImage', file)

}

// 这里改成你自己上传文件的逻辑

Api.uploadFile('/app?api=uploadImage', formData, res => {

this.setState({

src: res.data

})

})

}