前面我弄了一个关于上传图片到阿里oss 的jq包的 方法。
现在对其升级。
为何要升级?1,主要是减小服务器开销,本来就可以在请求之前完成,那么我们就不必要让数据库加工了。
原理:利用js 对图片进行压缩。压缩好了后,在进行上传。
直接上代码:
/* 图片上传前进行压缩
* 前端压缩
*主要是利用:canvas画板的功能重新绘制一下,就可以了。
// 压缩前将file转换成img对象
function 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)
}
})
}
/**
*
* 工具参数说明
* img 被压缩的img对象
* type 压缩后转换的文件类型
* mx 触发压缩的图片最大宽度限制
* mh 触发压缩的图片最大高度限制
*/
function 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
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') })
}
// 测试 async 异步方式,防止意外
async function upload(file){
const img = await readImg(file);//将file转换成img对象
const blob = await compressImg(img, file.type, 1000, 1000);//压缩大小为 1000x1000
const formData = new FormData();
formData.append('file', blob, 'xxx.jpg');//新生成的图片名字:xxx.jpg
axios.post('http://xxx.com/api',formData);//压缩完成 上传服务器
}
upload(file).catch(e => console.log(e))