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

news2024/10/5 18:26:32

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

两种方法 :

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

目录

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

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

1.新建imgUpload.js

2.全局引入封装的方法

3.页面中使用

 使用compressorjs第三方插件实现

1.compressorjs安装

2.方法封装

2.页面使用

3.头像上传处理


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

 借助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度问题

2.页面使用

import ImageCompressor from '@/utils/ImageCompressor'

3.头像上传处理

这里记得使用 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);
    },
  });
  
});

⭐️⭐️⭐️  作者:船长在船上
🚩🚩🚩  主页:来访地址船长在船上的博客
🔨🔨🔨  简介:CSDN前端领域博客专家,CSDN前端领域优质创作者,资深前端开发工程师,专注web前端领域开发,在CSDN分享工作中遇到的问题以及问题解决方法和对项目开发的实际案例总结以及新技术的认识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/37640.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

grafana变量使用

注&#xff1a;基于Grafana v8.3.6编写 1 添加变量 在dashboard界面点击setting&#xff0c;就能进入设置页面&#xff0c; 再点击Variables tab&#xff0c;就可以添加变量 比如我们添加一个系统架构的变量&#xff0c;用于区分Linux和Windows系统&#xff0c;通过node_una…

这可能是2022年把微服务讲的最全了:SpringBoot+Cloud+Docker

前言 最近几年&#xff0c;微服务可谓是大行其道。在业务模型不完善&#xff0c;超大规模流量的冲击的情况下&#xff0c;许多企业纷纷抛弃了传统的单体架构&#xff0c;拥抱微服务。这种模式具备独立开发、独立部署、可扩展性、可重用性的优点的同时&#xff0c;也带来这样一…

【云原生】K8S master节点更换IP以及master高可用故障模拟测试

文章目录一、前言二、配置 多个master 节点1&#xff09;节点信息1&#xff09;安装docker或containerd2&#xff09;安装kubeadm&#xff0c;kubelet和kubectl1、配置k8s yum源2、修改sandbox_image 镜像源3、配置containerd cgroup 驱动程序systemd4、开始安装kubeadm&#x…

SpringBoot SpringBoot 原理篇 1 自动配置 1.7 bean 的加载方式【五】

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇1 自动配置1.7 bean 的加载方式【五】1.7.1 register1 自动配置 1.7 bean 的…

FAIRNESS IN MACHINE LEARNING: A SURVEY 阅读笔记

论文链接 刚读完一篇关于机器学习领域研究公平性的综述&#xff0c;这篇综述想必与其有许多共通之处&#xff0c;重合部分不再整理笔记&#xff0c;可详见上一篇论文的笔记&#xff1a; A Survey on Bias and Fairness in Machine Learning 阅读笔记_Catherine_he_ye的博客 S…

红队隧道加密之MSF流量加密(二)

前言 如今大多数企业的内网都部署了流量审计服务, 用来专门分析流量特征, 比如后门特征和行为特征 若直接使用Metasploit对内网进行横向渗透, 其产生的流量会很容易被内网防护工具检测出来, 因此需对流量进行加密来绕过检测 这里介绍使用OpenSSL对MSF流量进行加密 演示步骤 …

这么高颜值的Kubernetes管理工具Lens,难道还不能C位出道吗

一直使用官方的Kubernetes Dashboard来管理k8s&#xff0c;也算很友好的一款UI工具&#xff0c;但显示的资源不全、查看日志有限、时间久了要重要登陆&#xff0c;所以找了一款外观漂亮&#xff0c;用户体验很好的管理平台Lens。 2 特性与安装 2.1 特性 Lens的优势主要有&…

齐聚绿城 | 锦江都城酒店聚焦中高端酒店投资新方向

提起广西&#xff0c;不少人能想到 “桂林山水甲天下”的桂林&#xff0c;亦或因一碗螺蛳粉闻名全国的柳州。又或荣登《国家地理》的涠洲岛。但在你不知晓的时候&#xff0c;南宁这座城在静静的等你发掘。南宁——南疆安宁&#xff0c;是山环水绕的“绿城”&#xff0c;也是北回…

windows系统cmake生成动态库无lib文件解决方法

作为cmake初学者&#xff0c;在windows系统下使用cmake生成c动态库时出现了下图所示问题&#xff0c;是关于lib文件。找了一圈&#xff0c;也没发现生成有lib文件。 在google上查&#xff0c;才发现windows系统下动态库生成lib文件&#xff0c;还需要添加以下命令&#xff1a; …

java 同步锁synchronized 解决线程共享数据重复操作问题

我们先来写一个买票程序 我们先创建一个包 在包下创建两个类 customException 线程类 负责编写抢票的主要逻辑 参考代码如下 public class customException implements Runnable {private int tickets 100;public void run () {while (tickets > 0){if(tickets > 0) {…

【语音增强】多维谱自适应小波语音信号去噪【含Matlab源码 1972期】

⛄一、自适应小波语音信号去噪 1 引言 语音信号在传输过程中&#xff0c;容易受到环境噪声和其他语音的干扰&#xff0c;降低了语音通信质量&#xff0c;影响了语音处理系统工作。所以&#xff0c;语音的净化处理技术&#xff0c;在现代语音通信和数字音频广播系统中起到愈来愈…

特殊的转义字符—— \b 退格字符 ASCII 08

引入 我们在写 C 语言题目时&#xff0c;经常会碰见这样的输出 11 123 1236 123410如果用循环的话&#xff0c;这个加号是个大问题&#xff0c;如果直接用 printf("%d")&#xff0c;最后会多一个加号&#xff0c;用 printf("%d") 则前面会多一个加号。想…

Qt编写视频监控管理平台(支持海康/大华/宇视/华为/天地伟业/H264/H265等)

一、前言 海康大华等厂家自己的客户端软件&#xff0c;基本上都是支持自家的设备&#xff0c;不支持其他家的摄像机和硬盘录像机&#xff0c;并不是因为技术上做不到&#xff0c;这些大厂要实现支持兼容其他的家的&#xff08;他们家的服务端或者收费的都是支持其他家的&#…

写个rpc调用,试试自己了解多少

什么是rpc rpc即是远程过程调用&#xff0c;简单来说就是调用其他服务的接口像调用自己的本地方法一样&#xff0c;通常我们的调用的时候不需要关心调用过程和底层的通信即可实现调用其他的服务&#xff1b; 大概流程就是服务模块双方都会向注册中心注册自己的服务&#xff0c…

开发工具vim

一、开发工具vim vim的安装&#xff1a;yum install -y vim 指令&#xff1a;vim --version可以查看当前的版本信息&#xff0c;没有弹出信息就是没有安装。 装的vim是没有相关配置文件的&#xff0c;配置文件需要后面自己装。 之前说过&#xff0c;vs2019是集成软件编译…

【畅购商城】购物车模块之修改购物车以及结算

目录 购物车操作&#xff1a;修改 分析 接口 后端实现&#xff1a;更新 前端实现&#xff1a;修改 前端实现&#xff1a;全选 后端实现&#xff1a;删除数据 结算 跳转页面 购物车操作&#xff1a;修改 分析 接口 PUT http://localhost:10010/cart-service/carts 后…

python数学基础——单词统计

这个练习使用的是英文的单词统计&#xff0c;使用split通过单词中间的空格来做区分&#xff0c;在遍历的过程中通过对【字典】类型进行【字典推导式】的处理来计算每个单词出现的频次。但是由于过程中我们通过re的正则表达式来替换掉了很多的符号&#xff0c;并没有替换成空&am…

【网页设计】web前端期末大作业html+css

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

Day12--自定义组件-渲染my-search组件的基本结构

1.自定义搜索组件 我的操作&#xff1a; 1》在uni_modules中右键新建uni_modules插件&#xff1a; 2》看看效果图&#xff1a; ************************************************************************************************************** 2.在分类页面的 UI 结构中&…

工作中常用的设计模式--策略模式

一般做业务开发&#xff0c;不太容易有大量使用设计模式的场景。这里总结一下在业务开发中使用较为频繁的设计模式。当然语言为Java&#xff0c;基于Spring框架。 1 策略模式(Strategy Pattern) 一个类的行为或方法&#xff0c;在运行时可以根据条件的不同&#xff0c;有不同的…