简介
当你希望上传图片时在前端展示,并希望像在想后端发送图片前进行压缩,那么可以看一下这一篇文章。
步骤
首先使用原声JS的方式创建input标签:
<input type="file" name="file" id="upload">
然后定义一下基础属性并获取input元素:
const ACCEPT = ['image/png', 'image/jpg', 'image/jpeg']
const MAXSIZE = 3 * 1024 * 1024
const MAXSIZE_STR = '3MB'
const upload = document.getElementById('upload')
添加监听事件,监听input上传图片时执行回调函数,解构赋值获取file,在file下解构赋值获取长度和上传图片片的类型:
upload.addEventListener('change',function(e){
const [file] = e.target.files
if(!file){
return
}
const {
size: fileSize,
type:fileType
} = file
})
接下来进行图片类型检查和图片大小检查:
if(!ACCEPT.includes(fileType)){
// 在这里提醒用户
upload.value = ''
return
}
if(fileSize>MAXSIZE){
// 提醒用户
upload.value = ''
return
}
当图片类型和图片大小都符合要求时,我们需要将图片转换成base64格式,获取base64格式可以通过FileReader():
function convertImageToBase64(file,cb){
let reader = new FileReader()
reader.addEventListener('load',function(e){
// e.target.result 就是我们需要的base64字符串
cb(e.target.result)
})
reader.readAsDataURL(file)
}
在获取到base64字符串后,我们就可以执行图片压缩的操作了,压缩图片我们需要用到canvas,在此之前我们应当获取图片的尺寸,并判断是否要更改尺寸到我们想要的目标大小:
function compress(base64Img, cb) {
let maxW = 540
let maxH = 540
const image = new Image()
image.addEventListener('load', function () {
let ratio //压缩比
let needCompress = false // 是否需要压缩
if (maxW < image.naturalWidth) {
needCompress = true
ratio = image.naturalWidth / maxW
maxH = image.naturalHeight / ratio
}
if (maxH < image.naturalHeight) {
needCompress = true
ratio = image.naturalHeight / maxH
maxW = image.naturalWidth / ratio
}
if (!needCompress) {
maxW = image.naturalWidth
maxH = image.naturalHeight
}
// 下面通过canvas压缩图片
const canvas = document.createElement('canvas')
canvas.setAttribute('id', '__compress__')
canvas.width = maxW
canvas.height = maxH
canvas.style.visibility = 'hidden'
document.body.append(canvas)
const ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, maxW, maxH)
ctx.drawImage(image, 0, 0, maxW, maxH)
//👇压缩图片比例 返回的compressImage就是压缩后的base64字符串
const compressImage = canvas.toDataURL('image/jpeg', 0.8)
//👇的回调函数可以调用服务器上传函数
cb(compressImage)
const _image = new Image();
_image.src = compressImage
document.body.appendChild(_image)
canvas.remove() // 移除canvas
})
image.src = base64Img
document.body.appendChild(image)
}
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="file" name="file" id="upload">
<script>
const ACCEPT = ['image/png', 'image/jpg', 'image/jpeg']
const MAXSIZE = 3 * 1024 * 1024
const MAXSIZE_STR = '3MB'
const upload = document.getElementById('upload')
upload.addEventListener('change', function (e) {
const [file] = e.target.files
if (!file) {
return
}
const {
size: fileSize,
type: fileType
} = file
// 图片支持类型检查
if (!ACCEPT.includes(fileType)) {
console.log(`不支持${fileType.split('/')}类型的文件!`);
upload.value = ''
return
}
// 图片大小检查
if (fileSize > MAXSIZE) {
console.log(`文件超出规定的${MAXSIZE_STR}大小`);
upload.value = ''
return
}
convertImageToBase64(file, compress);
// 获取base64
function convertImageToBase64(file, cb) {
let reader = new FileReader()
console.log(reader);
reader.addEventListener('load', function (e) {
cb(e.target.result, uploadImage)
})
reader.readAsDataURL(file)
}
// 图片压缩
function compress(base64Img, cb) {
let maxW = 540
let maxH = 540
const image = new Image()
image.addEventListener('load', function () {
let ratio //压缩比
let needCompress = false // 是否需要压缩
if (maxW < image.naturalWidth) {
needCompress = true
ratio = image.naturalWidth / maxW
maxH = image.naturalHeight / ratio
}
if (maxH < image.naturalHeight) {
needCompress = true
ratio = image.naturalHeight / maxH
maxW = image.naturalWidth / ratio
}
if (!needCompress) {
maxW = image.naturalWidth
maxH = image.naturalHeight
}
const canvas = document.createElement('canvas')
canvas.setAttribute('id', '__compress__')
canvas.width = maxW
canvas.height = maxH
canvas.style.visibility = 'hidden'
document.body.append(canvas)
const ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, maxW, maxH)
ctx.drawImage(image, 0, 0, maxW, maxH)
const compressImage = canvas.toDataURL('image/jpeg', 0.8) //压缩图片比例
cb(compressImage)
const _image = new Image();
_image.src = compressImage
document.body.appendChild(_image)
canvas.remove() // 移除canvas
})
image.src = base64Img
document.body.appendChild(image)
}
// 上传图片到服务器
function uploadImage(compressBase64Img) {
console.log('拿到了...' + compressBase64Img)
}
})
</script>
</body>
</html>