ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

el-upload使用http-request切片上传以及使用base64压缩图片展示缩略图

2022-07-20 18:00:28  阅读:172  来源: 互联网

标签:el canvas http 缩略图 item let file var 上传


html部分

<el-upload
class="avatar-uploader"
action="/file/upload_file/"
:on-remove="() => handleRemove(item)"
:http-request="(params) => httpUploadFile(params,item)"
:before-upload="beforeUpload"
accept="image/jpeg"
:file-list="item.fileList">
    <img v-if="item.value[0].thumb_url" :src="item.value[0].thumb_url" alt="" class="avatar" style="max-width: 500px;">
    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    <div slot="tip" class="el-upload__tip" v-if="item.value[0].url && item.value[0].thumb_url">
        <a :href="item.value[0].url" :download="item.value[0].name"><el-button type="success" size="small">下载原图</el-button></a>
        <el-button size="small" type="danger" @click="handleRemove(item)">删除图片</el-button>
    </div>
</el-upload>
<el-progress v-if="item.value[0].percent && item.value[0].percent != 0 && !(item.value[0].url && item.value[0].thumb_url)" :percentage="item.value[0].percent"></el-progress>


因为外部有循环所以里面的绑定值都有item,自行替换即可。

Javascript部分

// 取代原有的上传
httpUploadFile(params,item){
    item.value[0].name = params.file.name
    this.cutFile(params,item)
},


先替换原有的上传事件


// 大文件切片,async跟await可以传完一个再传下一个,需要同时传就去掉
async cutFile(params,item){
    let file = params.file
    let length = 1024 * 1024 * 5; // 这里是每一个分片的大小
    let total_number = Math.ceil(file.size / length); // 使用进一法,来确定分片的个数
    let start = 0; // 分片的初始位置
    let end = length; // 分片的结束位置
    let parr = []; // 这里为promise.all方法准备一个数组
    let percentInfo = {
        fileSize:file.size,
        length:length,
    } //给进度条用的
    for (let i = 1; i <= total_number; i++) {
        // 这里开始分片,并且把每一个分片上传到服务器
        let blob = file.slice(start, end); // 得到一个分片
        start = end; // 调整下一个分片的起始位置
        end = start + length; // 调整下一个分片的结束位置
        if (end > file.size) {
            end = file.size; // 这里对最后的一个分片结束位置进行调整
        }
        let formdata = new FormData(); // 创建一个FormData对象,准备传送数据
        formdata.append("file", blob); // 将分片数据放入formdata
        formdata.append("blob_num", i); // 这是第几块
        formdata.append("total_blob_num", total_number); // 总的几块
        formdata.append("file_name", file.name); // 文件名
        // formdata组装好之后,调用pro()函数,返回一个promise对象,并把它放入parr数组中,方便后面的promise.all方法使用
        parr.push(await _this.submitCutFile(formdata,item,percentInfo));
    }
// 以上for循环结束之后,parr数组中就全部是分片上传的promise的对象了,此时我们使用promise.all方法,等待所有上传都成功执行后,再向服务器发送一个请求,也就是上传完成,让服务器组装分片的请求
    Promise.all(parr).then(res=>{
        if(res.length == parr.length){ // 如果返回成功的数组长度和parr的数组长度相等,说明分片全部上传成功
            this.fileTobase64(file).then(res =>{
                _this.compressImg(res,1000,0.5).then(res2 =>{
                    resolve = item.value[0].thumb_url = res2
                })
            })
            item.value[0].url = JSON.parse(res[res.length-1]).file_path
        }
    }).catch(res =>{
        _this.$message.warning("上传失败,请重新上传")
    })
},


把文件切片,使用了async跟await是为了传完一个切片完再传下一个,不需要的话去掉就行
在promise.all的是为了把大图片变成base64并用canvas压缩变成缩略图方便预览

// 将上传的文件先转为base64进行预览
 fileTobase64(file){
     return new Promise((resolve, reject) => {
         var reader = new FileReader();
         reader.onload = function(e){
             resolve(e.target.result)
         }
         reader.readAsDataURL(file)
     })
 },
 // 把base64图片渲染成canvas进行压缩
 compressImg(base64String, w, quality) {
     var getMimeType = function(urlData) {
         var arr = urlData.split(",");
         var mime = arr[0].match(/:(.*?);/)[1];
         return mime;
     };
     var newImage = new Image();
     var imgWidth, imgHeight;

     var promise = new Promise(resolve => (newImage.onload = resolve));
     newImage.src = base64String;
     return promise.then(() => {
         imgWidth = newImage.width;
         imgHeight = newImage.height;
         var canvas = document.createElement("canvas");
         var ctx = canvas.getContext("2d");
         if (Math.max(imgWidth, imgHeight) > w) {
             if (imgWidth > imgHeight) {
                 canvas.width = w;
                 canvas.height = (w * imgHeight) / imgWidth;
             } else {
                 canvas.height = w;
                 canvas.width = (w * imgWidth) / imgHeight;
             }
         } else {
             canvas.width = imgWidth;
             canvas.height = imgHeight;
         }
         ctx.clearRect(0, 0, canvas.width, canvas.height);
         ctx.drawImage(newImage, 0, 0, canvas.width, canvas.height);
         var base64 = canvas.toDataURL(
             getMimeType(base64String),
             quality
         );
         return base64;
     });
 },

上传每个切片,并正确设置进度条

 // 上传切片,设置进度条
 submitCutFile(formData,item,percentInfo){
     let i = formData.get('blob_num')
     console.log(i)
     console.log(formData.get('total_blob_num'))
     return new Promise((resolve,reject)=>{
         $.ajax({
             type:"post",
             url:"/cl/test/test_upload/", // 后台上传文件的地址
             data:formData,
             contentType: false, // 这个不能少,ajax上传文件是不能少的
             processData: false, // 这个不能少,ajax上传文件必传false
             xhr: function() {
                 let newxhr = new XMLHttpRequest()
                 // 添加文件上传的监听
                 // onprogress:进度监听事件,只要上传文件的进度发生了变化,就会自动的触发这个事件
                 newxhr.upload.onprogress = function(e) {
                     console.log(e)
                     let percent = (((i-1)*percentInfo.length + e.loaded)/percentInfo.fileSize)*100
                     item.value[0].percent = Number(percent.toFixed(1))
                 }
                 return newxhr
             },
             success:function(res){
                 resolve(res)
             },
             fail: function () {
                 reject()
             }
         })
     })
 },

 

标签:el,canvas,http,缩略图,item,let,file,var,上传
来源: https://www.cnblogs.com/Sijin-0109/p/16499011.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有