vue2+element ui 项目使用Upload 上传组件,实现图片压缩
element
A Vue.js 2.0 UI Toolkit for Web
项目地址:https://gitcode.com/gh_mirrors/eleme/element
免费下载资源
·
使用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;
/* if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
} */
// 定义需要上传的文件
let formData = new FormData()
formData.append('file', file.raw)
console.log('formData', formData)
console.log('formData.getAll()', formData.getAll(['file']))
// this.imageUrl = URL.createObjectURL(file.raw)
let result = await transitionBase64(file.raw)
let compressImgResult = await compressImg(result, 50 * 1024)
// console.log(111, result)
console.log('压缩后的文件', compressImgResult)
console.log('压缩后的文件转blob', dataURItoBlob(compressImgResult))
console.log('压缩后的文件转file对象', base64ToFile(compressImgResult, file.name.split('.')[0]))
// this.imageUrl = URL.createObjectURL(dataURItoBlob(compressImgResult))
// 显示压缩后的图片
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封装压缩图片函数
//
// 封装上传图片时的压缩方法及其base64转bolb
// 将bolb转换成base64
export function transitionBase64(blob) {
return new Promise((resolve, reject) => {
// 创建一个FileReader实例
const reader = new FileReader();
let base64String
// 设置FileReader的onload事件处理程序,当转换完成时调用
reader.onload = function(event) {
// 事件的result属性包含了转换完成的数据
base64String = event.target.result;
// 输出Base64编码的字符串
resolve(base64String)
};
// 使用readAsDataURL方法开始转换Blob为Base64
reader.readAsDataURL(blob);
})
}
/**
* base64转图片File
* @param {String} base64 图片base64
* @param {String} fileName 图片名称| 默认 → imgName
* @returns File 返回转换后的file数据类型
*/
export function base64ToFile (base64, fileName = 'imgName') {
// 将base64按照 , 进行分割 将前缀 与后续内容分隔开
let data = base64.split(','),
// 利用正则表达式 从前缀中获取图片的类型信息(image/png、image/jpeg、image/webp等)
type = data[0].match(/:(.*?);/)[1],
// 从图片的类型信息中 获取具体的文件格式后缀(png、jpeg、webp)
suffix = type.split('/')[1],
// 使用atob()对base64数据进行解码 结果是一个文件数据流 以字符串的格式输出
bstr = window.atob(data[1]),
// 获取解码结果字符串的长度
n = bstr.length,
// 根据解码结果字符串的长度创建一个等长的整形数字数组
// 但在创建时 所有元素初始值都为 0
u8arr = new Uint8Array(n)
// 将整形数组的每个元素填充为解码结果字符串对应位置字符的UTF-16 编码单元
while (n--) {
// charCodeAt():获取给定索引处字符对应的 UTF-16 代码单元
u8arr[n] = bstr.charCodeAt(n)
}
// 利用构造函数创建File文件对象
// new File(bits, name, options)
const file = new File([u8arr], `${fileName}.${suffix}`, {
type: type
})
// 返回file
return file
}
// base64 转 blob
export function dataURItoBlob(base64Data) {
var byteString;
if(base64Data.split(',')[0].indexOf('base64') >= 0)
byteString = atob(base64Data.split(',')[1]);//base64 解码
else{
byteString = unescape(base64Data.split(',')[1]);
}
var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];//mime类型
// var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
// var ia = new Uint8Array(arrayBuffer);//创建视图
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;
}
/**
* 压缩图片 返回base64
* @param {base64} imgFile 图片base64
* @param {Number} maxSize 上传压缩图片的大学| 默认 → 50 * 1024 kb
* @returns File 返回转换后的file数据类型
*/
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.toFixed(2)));
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);
}
// 对resultBlob做一些事情,比如从它创建一个新图像或保存它。
console.log('压缩后的文件newBase64Image', newBase64Image)
console.log('压缩后的文件fileSize', fileSize)
resolve(newBase64Image)
}
})
}
// 计算base64编码图片大小
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);
}
GitHub 加速计划 / eleme / element
54.06 K
14.63 K
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:3 个月前 )
c345bb45
7 个月前
a07f3a59
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update table.md
* Update transition.md
* Update popover.md 7 个月前
更多推荐
已为社区贡献4条内容
所有评论(0)