经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
Vue.js实现文件上传压缩优化处理技巧
来源:jb51  时间:2022/11/28 8:56:00  对本文有异议

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

两种方法 :

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

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

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

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

<canvas>简单实例如下:

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

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

使用 style 属性来添加边框:

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

1.新建imgUpload.js

 将base64转换为file文件

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

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

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

在画布上定位图像:

  1. context.drawImage(img,x,y);

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

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

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

  1. canvas.toDataURL(type, option);

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

  1. const imgZip = (file) => {
  2. let imgZipStatus = new Promise((resolve, reject) => {
  3. let canvas = document.createElement("canvas"); // 创建Canvas对象(画布)
  4. let context = canvas.getContext("2d");
  5. let img = new Image();
  6. img.src = file.content; // 指定图片的DataURL(图片的base64编码数据)
  7. var Orientation = '';
  8. img.onload = () => {
  9. // canvas.width = 400;
  10. // canvas.height = 300;
  11. canvas.width = img.width;
  12. canvas.height = img.height;
  13. context.drawImage(img, 0, 0, canvas.width, canvas.height);
  14. file.content = canvas.toDataURL(file.file.type, 0.5); // 0.92为默认压缩质量
  15. let files = dataURLtoFile(file.content, file.file.name);
  16. resolve(files)
  17. }
  18. })
  19. return imgZipStatus;
  20. };

导出方法imgZip

  1. export {
  2. imgZip
  3. }

2.全局引入封装的方法

main.js

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

3.页面中使用

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

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

限制上传数量

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

禁用文件上传

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

  1. <van-uploader disabled />

 限制上传大小图片

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

上传之前的图片验证 

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

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

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

  1. // 头像上传
  2. afterCard(file) {
  3. this.$imgUpload.imgZip(file).then(resData => {
  4. const formData = new FormData();
  5. formData.append("file", resData);
  6. // 请求接口上传图片到服务器
  7. uploadImg(formData).then(res => {
  8. console.log(res, "图片上传");
  9. if (res.code == 200) {
  10. console.log(res.data,"res.data")
  11. let params = {
  12. bbsIconUrl: res.data,
  13. userId: this.id
  14. };
  15. compileUserInfo(params)
  16. .then(resImg => {
  17. console.log(resImg, "resImg");
  18. if (resImg.code == 200) {
  19. this.Personal.iconUrl =res.data;
  20. this.$toast("头像修改成功");
  21. } else {
  22. this.$toast(resImg.msg);
  23. }
  24. })
  25. .catch(error => {});
  26. } else {
  27. this.$toast(res.msg);
  28. }
  29. });
  30. });
  31. },

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

示例:

  1. <input type="file" id="file" accept="image/*">
  1. import axios from 'axios';
  2. document.getElementById('file').addEventListener('change', (e) => {
  3. const file = e.target.files[0];
  4. if (!file) {
  5. return;
  6. }
  7. this.$imgUpload.imgZip(file).then(resData => {
  8. const formData = new FormData();
  9. formData.append("file", resData);
  10. //接口调用
  11. axios.post('/upload', formData).then((res) => {
  12. console.log('Upload success');
  13. });
  14. })
  15. });

 使用compressorjs第三方插件实现

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

语法:

  1. new Compressor(file[, options])

1.compressorjs安装

  1. npm install compressorjs --save

2.方法封装

ImageCompressor.js

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

  1. import Compressor from 'compressorjs';
  2. export default function ImageCompressor(file, backType, quality) {
  3. return new Promise((resolve, reject) => {
  4. new Compressor(file, {
  5. quality:quality || 0.6, //压缩质量
  6. success(result) {
  7. if (!backType || backType == 'blob') {
  8. resolve(result)
  9. } else if (backType == 'file') {
  10. resolve(file)
  11. } else {
  12. resolve(file)
  13. }
  14. // resolve(result);
  15. },
  16. error(err) {
  17. console.log("图片压缩失败");
  18. reject(err);
  19. }
  20. })
  21. })
  22. }

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

3.页面使用

  1. import ImageCompressor from '@/utils/ImageCompressor'

4.头像上传处理

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

  1. // 头像上传
  2. async afterCard(file) {
  3. let newFile = await ImageCompressor(file.file, 'file', 0.6); //图片压缩
  4. const formData = new FormData();
  5. formData.append("file", newFile);
  6. uploadImg(formData).then(res => {
  7. if (res.code == 200) {
  8. this.centerInfo.iconUrl = res.data;
  9. let params = {
  10. iconUrl: res.data,
  11. id: this.id,
  12. loginType: this.loginType
  13. };
  14. updateMineIconUrl(params)
  15. .then(resImg => {
  16. console.log(resImg, "resImg");
  17. if (resImg.code == 200) {
  18. this.$toast("头像修改成功");
  19. } else {
  20. this.$toast(res.msg);
  21. }
  22. })
  23. .catch(error => {});
  24. } else {
  25. this.$toast(res.msg);
  26. }
  27. });
  28. },

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

示例:

  1. <input type="file" id="file" accept="image/*">
  1. import axios from 'axios';
  2. import Compressor from 'compressorjs';
  3. document.getElementById('file').addEventListener('change', (e) => {
  4. const file = e.target.files[0];
  5. if (!file) {
  6. return;
  7. }
  8. new Compressor(file, {
  9. quality: 0.6,
  10. success(result) {
  11. const formData = new FormData();
  12. formData.append('file', result, result.name);
  13. //接口调用
  14. axios.post('/upload', formData).then(() => {
  15. console.log('Upload success');
  16. });
  17. },
  18. error(err) {
  19. console.log(err.message);
  20. },
  21. });
  22. });

到此这篇关于Vue.js实现文件上传压缩优化处理的文章就介绍到这了,更多相关vue文件上传内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号