核心方法:canvas.toDataURL
单纯按比例压缩
// 压缩文件
async compressImg (file, fileName) {
let reader = new FileReader()
// 将读取到的文件编码成DataURL
reader.readAsDataURL(file)
// 压缩图片
return new Promise((resolve, reject) => {
reader.onload = function (ev) {
try {
// 读取图片来获得上传图片的宽高
let img = new Image()
img.src = ev.target.result
img.onload = function (ev) {
// 将图片绘制到canvas画布上进行压缩
let canvas = document.createElement("canvas")
let context = canvas.getContext("2d")
let imgwidth = img.width
let imgHeight = img.height
// ?按比例缩放后图片宽高;
let targetwidth = imgwidth
let targetHeight = imgHeight
// 如果原图宽大于最大宽度
if (targetwidth > targetHeight) {
// 原图宽高比例
let scale = targetHeight / 1280
targetHeight = 1280
targetwidth = targetwidth / scale
} else {
// 原图宽高比例
let scale = targetwidth / 1280
targetwidth = 1280
targetHeight = targetHeight / scale
}
// ?缩放后高度仍然大于最大高度继续按比例缩小
canvas.width = targetwidth //canvas的宽=图片的宽
canvas.height = targetHeight //canvas的高=图片的高
context.clearRect(0, 0, canvas.width, canvas.height)
context.drawImage(this, 0, 0, canvas.width, canvas.height)
let imageDataURL = ""
// 如果图片小于0.2Mb,不进行压缩,并返回二进制流
if (file.size <= 200 * 1024) {
imageDataURL = canvas.toDataURL("image/jpeg")
resolve(file)
} else {
// todo 压缩文件大小比例
imageDataURL = canvas.toDataURL("image/jpeg", 0.5)
// 去掉URL的头,并转换为byte
const imageBytes = window.atob(imageDataURL.split(',')[1])
// 处理异常,将ascii码小于0的转换为大于0
const arrayBuffer = new ArrayBuffer(imageBytes.length)
const uint8Array = new Uint8Array(arrayBuffer)
for (let i = 0; i < imageBytes.length; i++) {
uint8Array[i] = imageBytes.charCodeAt(i)
}
let mimeType = imageDataURL.split(',')[0].match(/:(.*?);/)[1]
let newFile = new File([uint8Array], fileName, { type: mimeType || 'image/jpeg' })
resolve(newFile)
}
}
} catch (error) {
console.log("压缩错误", error)
}
}
})
},
如需压缩到指定大小,请循环压缩。
网友评论