// 压缩函数
async function compressImage(file, maxSize = 1024 * 1024, maxWidth = 1920) {
return new Promise((resolve, reject) => {
if (!file.type.startsWith('image/')) {
return
}
const img = new Image()
// 解决跨域问题(若图片来自本地/同域可省略)
img.crossOrigin = 'anonymous'
const reader = new FileReader()
reader.onload = (e) => {
img.src = e.target.result
}
reader.onerror = () => {}
reader.readAsDataURL(file)
img.onload = () => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
if (!ctx) {
return
}
let { width, height } = img
if (width > maxWidth) {
const scale = maxWidth / width
width = maxWidth
height = height * scale
}
canvas.width = width
canvas.height = height
ctx.drawImage(img, 0, 0, width, height)
let quality = 0.9
const mimeType = file.type || 'image/jpeg'
// 压缩核心函数
function compress() {
canvas.toBlob(
(blob) => {
if (!blob) {
return
}
if (blob.size <= maxSize || quality <= 0.1) {
const randomsIdNum = uuidv4()
const fileName = `${randomsIdNum}_${file.name.replace(/\.\w+$/, mimeType === 'image/jpeg' ? '.jpg' : '.png')}`
const compressedFile = new File([blob], fileName, {
type: mimeType,
lastModified: Date.now()
})
resolve(compressedFile)
return
}
quality -= 0.1
compress()
},
mimeType,
quality
)
}
compress()
}
img.onerror = () => {}
})
}
async function convertFileToBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(file);
});
}