Vue.js实现文件上传压缩优化处理技巧

 

vue js实现文件上传压缩优化处理

两种方法 :

  • 第1种是借助canvas的封装的文件压缩上传
  • 第2种(扩展方法)使用compressorjs第三方插件实现

下面来详细介绍两种方法:

 

借助canvas的封装的文件压缩上传

封装之前,先要对canvas相关的方法有所了解

<canvas>简单实例如下:

<canvas id="myCanvas" width="200" height="100"></canvas>

注意:标签通常需要指定一个id属性 (或者其他), width 和 height 属性定义的画布的大小.

使用 style 属性来添加边框:

<canvas id="myCanvas" width="200" height="100"
style="border:1px solid #000000;">
</canvas>

1.新建imgUpload.js

将base64转换为file文件

const dataURLtoFile = (dataurl, filename) => { 
  let arr = dataurl.split(',')
  let mime = arr[0].match(/:(.*?);/)[1]
  let bstr = atob(arr[1])
  let n = bstr.length
  let u8arr = new Uint8Array(n)
  while (n--) {
      u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], filename, { type: mime })
};

使用canvas的方法实现(拓展)

drawImage() 方法在画布上绘制画布。

在画布上定位图像:

context.drawImage(img,x,y);

在画布上定位图像,并规定图像的宽度和高度:剪切图像,并在画布上定位被剪切的部分:

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

canvas的toDataURL()方法是返回一个包含图片展示的 数据URL。可以使用type参数其类型,默认为png格式

canvas.toDataURL(type, option);

option表示0到1之间的取值,选定图片的质量,默认值是0.92

const imgZip = (file) => {
  let imgZipStatus = new Promise((resolve, reject) => {
      let canvas = document.createElement("canvas"); // 创建Canvas对象(画布)
      let context = canvas.getContext("2d");
      let img = new Image();
      img.src = file.content; // 指定图片的DataURL(图片的base64编码数据)
      var Orientation = '';
      img.onload = () => {
          // canvas.width = 400;
          // canvas.height = 300;
          canvas.width = img.width;
          canvas.height = img.height;
          context.drawImage(img, 0, 0, canvas.width, canvas.height);         
          file.content = canvas.toDataURL(file.file.type, 0.5); // 0.92为默认压缩质量
          
          let files = dataURLtoFile(file.content, file.file.name);
          resolve(files)
      }
  })
  return imgZipStatus;
};

导出方法imgZip

export {
  imgZip
}

2.全局引入封装的方法

main.js

// 引入imgUpload方法
import * as imgUpload from "./utils/imgUpload"
Vue.prototype.$imgUpload = imgUpload;

3.页面中使用

这里使用了vant ui框架,实现的头像上传,如果用原生的input file方法也是一样的使用方式

<van-uploader :after-read="afterCard" :before-read="beforeRead" accept="image/*" class="arrart"
              :max-size="10240 * 1024" @oversize="onOversize" ref="uploadFile">
              <!-- <div class="loadingWrap" v-show="personCardloading">
                <van-loading class="colorCom uploadText" color="#fff" size="24px">{{uploadText}}</van-loading>
              </div> -->
              <van-image class="iconImg" round :src="Personal.iconUrl?$baseImgUrl+Personal.iconUrl:require('../../assets/img/touciang.png')" width="64" height="64" />
            </van-uploader>

限制上传数量

通过max-count属性可以限制上传文件的数量,上传数量达到限制后,会自动隐藏上传区域。

禁用文件上传

通过disabled属性禁用文件上传。

<van-uploader disabled />

限制上传大小图片

// 限制上传大小图片
  onOversize(file) {
    console.log(file, "file");
    this.$toast("文件大小不能超过 10M");
  },

上传之前的图片验证

    // 上传之前的图片验证
  beforeRead(file) {
    console.log(file, "file,123");
    if (this.$utils.isImage(file.name)) {
      return true;
    } else {
      this.$toast("请上传图片格式");
    }
  },

afterCard方法,当提交了头像,先进行压缩处理,再去把formData文件流 作为参数调用接口,

获取到后台返回的图片路径,再调用更新头像接口,把获取的数据赋值显示头像的img.

// 头像上传
  afterCard(file) {
    this.$imgUpload.imgZip(file).then(resData => {
      const formData = new FormData();
      formData.append("file", resData);
      // 请求接口上传图片到服务器
      uploadImg(formData).then(res => {
        console.log(res, "图片上传");
        if (res.code == 200) {
          console.log(res.data,"res.data")
          let params = {
            bbsIconUrl: res.data,
            userId: this.id
          };
          compileUserInfo(params)
            .then(resImg => {
              console.log(resImg, "resImg");
              if (resImg.code == 200) {
                this.Personal.iconUrl =res.data;
                
                this.$toast("头像修改成功");
              } else {
                this.$toast(resImg.msg);
              }
            })
            .catch(error => {});
        } else {
          this.$toast(res.msg);
        }
      });
    });
  },

如果这里使用原生的input file,可按照如下操作

示例:

<input type="file" id="file" accept="image/*"> 
import axios from 'axios';

document.getElementById('file').addEventListener('change', (e) => {
const file = e.target.files[0];

if (!file) {
  return;
}
this.$imgUpload.imgZip(file).then(resData => {
      const formData = new FormData();
      formData.append("file", resData);

      //接口调用
      axios.post('/upload', formData).then((res) => {
          console.log('Upload success');
      });
})

});

 

使用compressorjs第三方插件实现

compressorjs 是一个开源的图片处理库,提供了图片压缩、图片旋转等能力

语法:

new Compressor(file[, options]) 

1.compressorjs安装

npm install compressorjs --save

2.方法封装

ImageCompressor.js

quality:quality || 0.6, //压缩质量,图片压缩比 0-1

import Compressor from 'compressorjs';
export default function ImageCompressor(file, backType, quality) {
  return new Promise((resolve, reject) => {
      new Compressor(file, {
			quality:quality || 0.6, //压缩质量
			success(result) {
              if (!backType || backType == 'blob') {
                  resolve(result)
              } else if (backType == 'file') {
                  resolve(file)
              } else {
                  resolve(file)
              }
				// resolve(result);
			},
			error(err) {
              console.log("图片压缩失败");
				reject(err);
			}
		})
  })
}

此插件还能解决ios移动端拍照图片翻转90度问题

3.页面使用

import ImageCompressor from '@/utils/ImageCompressor'

4.头像上传处理

这里记得使用 async await,注意使用的file取值,与第一种的方法有所不同

 // 头像上传
  async afterCard(file) {
      let newFile = await ImageCompressor(file.file, 'file', 0.6); //图片压缩
      const formData = new FormData();
      formData.append("file", newFile);
      uploadImg(formData).then(res => {
        if (res.code == 200) {
          this.centerInfo.iconUrl = res.data;
          let params = {
            iconUrl: res.data,
            id: this.id,
            loginType: this.loginType
          };
          updateMineIconUrl(params)
            .then(resImg => {
              console.log(resImg, "resImg");
              if (resImg.code == 200) {
             
                this.$toast("头像修改成功");
              } else {
                this.$toast(res.msg);
              }
            })
            .catch(error => {});
        } else {
          this.$toast(res.msg);
        }
      });
  
  },

如果这里使用原生的input file,可按照如下操作

示例:

<input type="file" id="file" accept="image/*"> 
import axios from 'axios';
import Compressor from 'compressorjs';

document.getElementById('file').addEventListener('change', (e) => {
const file = e.target.files[0];

if (!file) {
  return;
}

new Compressor(file, {
  quality: 0.6,

  success(result) {
    const formData = new FormData();

    formData.append('file', result, result.name);
      //接口调用
    axios.post('/upload', formData).then(() => {
      console.log('Upload success');
    });
  },
  error(err) {
    console.log(err.message);
  },
});

});

关于Vue.js实现文件上传压缩优化处理的文章就介绍至此,更多相关vue文件上传内容请搜索编程宝库以前的文章,希望以后支持编程宝库

print-js官网链接: https://printjs.crabbly.com/ 下载依赖npm install print-js --save ...