canvas图片压缩
用canvas实现图片压缩, 主要原理是获取图片真实宽高, 然后进行等比缩放, 最后用canvas进行绘制
代码
<input type="file" id="upload" />
const upload = document.getElementById('upload')
const ACCEPT = ['image/png', 'image/jpg', 'image/jpeg']
const MAXSIZE = 1024 * 1024 * 3
const MAXSIZE_STR = '3MB'
/* 转换为base64 */
function coverImageToBase64(file, cb) {
let reader = new FileReader()
reader.addEventListener('load', (e) => {
const base64Image = e.target.result
cb && cb(base64Image)
reader = null
})
reader.readAsDataURL(file)
}
/* 压缩核心方法 */
function compress(base64Image, cb) {
const image = new Image()
let max_width = 1024
let max_height = 1024
image.addEventListener('load', (e) => {
// 压缩比
let ratio
// 是否压缩
let needCompress = false
if (image.naturalWidth > max_width) {
needCompress = true
ratio = image.naturalWidth / max_width
// 同步压缩高度
max_height = image.naturalHeight / ratio
}
if (image.naturalHeight > max_height) {
needCompress = true
ratio = image.naturalHeight / max_height
max_width = image.naturalWidth / ratio
}
// 不需要压缩获取图片实际宽高
if (!needCompress) {
max_width = image.naturalWidth
max_height = image.naturalHeight
}
const canvas = document.createElement('canvas')
canvas.setAttribute('id', '_compress_')
canvas.width = max_width
canvas.height = max_height
canvas.style.visibility = 'hidden'
document.body.appendChild(canvas)
const ctx = canvas.getContext('2d')
// 清除空间内的像素
ctx.clearRect(0, 0, max_width, max_height)
ctx.drawImage(image, 0, 0, max_width, max_height)
// 输出压缩的base64格式
const compressImage = canvas.toDataURL('image/jpeg', 0.9)
cb && cb(compressImage)
const _image = new Image()
_image.src = compressImage
document.body.appendChild(_image)
canvas.remove()
// console.log('压缩比: ', image.src.length / _image.src.length)
})
image.src = base64Image
document.body.appendChild(image)
}
/* 上传 */
function uploadToServer(compressImg) {
return 'success'
}
/* 检查上传文件 */
upload.addEventListener('change', () => {
const [file] = e.target.files
if (!file) return
const {
type: fileType,
size: fileSize
} = file
if (!ACCEPT.includes(fileType) < 0) {
alert(`不支持${fileType}类型的图片`)
return
}
if (fileSize > MAXSIZE) {
alert(`文件超出${MAXSIZE_STR}`)
upload.value = ''
return
}
coverImageToBase64(file, (base64Img) => compress(base64Img, uploadToServer))
})