使用element ui的Upload 上传组件,实现图片压缩
在template中代码
<el-form-item
label="图片"
:label-width="'120px'"
prop="menuName"
>
<el-upload
action="#"
class="avatar-uploader"
:auto-upload="false"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:on-change="onChange"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
script中代码
<script>
import {
transitionBase64,
compressImg,
dataURItoBlob,
base64ToFile
} from '@/utils/compressTransitionImg.js'
export default {
data() {
return {
imageUrl: '',
}
},
methods: {
async onChange(file, fileList) {
console.log('file, fileList', file, fileList)
console.log('上传的文件file', file)
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
let formData = new FormData()
formData.append('file', file.raw)
console.log('formData', formData)
console.log('formData.getAll()', formData.getAll(['file']))
let result = await transitionBase64(file.raw)
let compressImgResult = await compressImg(result, 50 * 1024)
console.log('压缩后的文件', compressImgResult)
console.log('压缩后的文件转blob', dataURItoBlob(compressImgResult))
console.log('压缩后的文件转file对象', base64ToFile(compressImgResult, file.name.split('.')[0]))
this.imageUrl = URL.createObjectURL(base64ToFile(compressImgResult, file.name))
},
handleAvatarSuccess(res, file) {
this.imageUrl = URL.createObjectURL(file.raw);
},
beforeAvatarUpload(file) {
console.log('上传的文件file', file)
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return true;
return isJPG && isLt2M;
},
handleRemove(file) {
console.log(file);
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
handleDownload(file) {
console.log(file);
}
}
}
</script>
新建compressTransitionImg.js封装压缩图片函数
export function transitionBase64(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
let base64String
reader.onload = function(event) {
base64String = event.target.result;
resolve(base64String)
};
reader.readAsDataURL(blob);
})
}
export function base64ToFile (base64, fileName = 'imgName') {
let data = base64.split(','),
type = data[0].match(/:(.*?);/)[1],
suffix = type.split('/')[1],
bstr = window.atob(data[1]),
n = bstr.length,
u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
const file = new File([u8arr], `${fileName}.${suffix}`, {
type: type
})
return file
}
export function dataURItoBlob(base64Data) {
var byteString;
if(base64Data.split(',')[0].indexOf('base64') >= 0)
byteString = atob(base64Data.split(',')[1]);
else{
byteString = unescape(base64Data.split(',')[1]);
}
var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];
var ia = new Uint8Array(byteString.length);
for(var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
var blob = new Blob([ia], {
type: mimeString
});
return blob;
}
export function compressImg(imgFile, maxSize = 50 * 1024) {
return new Promise((resolve, reject) => {
var img = new Image();
img.src = imgFile
console.log('imgFile', imgFile)
img.onload = function () {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var width = img.width;
var height = img.height;
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
var quality = 0.8;
let newBase64Image = canvas.toDataURL('image/jpeg', quality);
let fileSize = getBase64ImageSize(newBase64Image);
if (fileSize > maxSize) {
const qualityArr = [], step = 0.01;
for (let i = step; i <= quality; i += step) {
qualityArr.push(parseFloat(i));
}
let left = 0,
right = qualityArr.length - 1;
do {
console.log('循环次数fileSize', fileSize)
const mid = Math.floor((left + right) / 2);
newBase64Image = canvas.toDataURL('image/jpeg', qualityArr[mid]);
fileSize = getBase64ImageSize(newBase64Image);
if (fileSize > maxSize) {
right = mid - 1;
} else {
left = mid + 1;
}
} while (left <= right);
}
console.log('压缩后的文件newBase64Image', newBase64Image)
console.log('压缩后的文件fileSize', fileSize)
resolve(newBase64Image)
}
})
}
function getBase64ImageSize(base64) {
const indexBase64 = base64.indexOf('base64,');
if (indexBase64 < 0) return -1;
const str = base64.substr(indexBase64 + 6);
return (str.length * 0.75).toFixed(2);
}
参考