业务背景:业务上需求满足上传的图片不能太大,但是有时候上传的图片确实超过了限制大小,所以前端这边可以将图片压缩再上传,
亦或者是上传给后端接口的图片只能是指定格式,我们前端需要将图片后缀转化,也可以处理!封装的使用方法如下:

使用 canvas 对图片进行压缩处理:

  1. /*

  * 压缩图片

  * param  file: 接受的文件对象

  * param  option: 图片压缩的参数  具体可以看一下 canvas的官网介绍 :https://www.canvasapi.cn/HTMLCanvasElement/toDataURL

 */

  1. export function compressPic(
  2. file: any,
  3. option?: {
  4. maxWidth?: number;
  5. maxHeight?: number;
  6. minSize?: number;
  7. mimeType?: string;
  8. quality?: number;
  9. }
  10. ): any {
  11. const maxWidth = option?.maxWidth || 750; // 最大宽度
  12. const maxHeight = option?.maxHeight || 750; // 最大高度
  13. const minSize = option?.minSize ?? 300 * 1024; // 最小压缩文件大小 300kb
  14. const mimeType = option?.mimeType || "image/jpeg"; // 默认图片类型
  15. let qualitys: number = option?.quality || 0.8; // 默认压缩阙值0.75
  16. // 根据文件大小设置不同的默认压缩质量
  17. if (parseInt((file.size / 1024).toFixed(2)) < 1024) {
  18. qualitys = 0.85;
  19. }
  20. if (5 * 1024 < parseInt((file.size / 1024).toFixed(2))) {
  21. qualitys = 0.92;
  22. }
  23.  
  24. // 如果上传的是多个文件,递归处理每个文件
  25. if (file[0]) {
  26. return Promise.all(
  27. Array.from(file).map((e: any) => compressPic(e, option))
  28. );
  29. } else {
  30. return new Promise((resolve) => {
        // 这里我注释了是因为我们没有这个需求,如果有这个需求的可以将这个注释放开就可以了
  31. // // 如果图片大小小于300KB,直接返回原始图片数据
  32. // if (file.size < minSize) {
  33. // resolve({
  34. // file: file,
  35. // });
  36. // } else {
  37. // 创建FileReader对象,异步读取存储在客户端上的文件内容
  38. const reader: FileReader = new FileReader();
  39. // 读取操作完成时触发该事件,使用格式(必须将接收到的数据从onload发送到其他函数):reader.onload = e => {}
  40. reader.onload = ({ target }: ProgressEvent<FileReader>) => {
  41. // console.log("target----", target);
  42.  
  43. //创建img元素
  44. const image = new Image() as any;
  45. // 图片加载完成后异步执行,当image的src发生改变,浏览器就会跑去加载这个src里的资源,这个操作是异步的。
  46. image.onload = async () => {
  47. // 创建一个新的画布元素和上下文,用于绘制压缩后的图片
  48. const canvas = document.createElement("canvas");
  49. const context = canvas.getContext("2d") as any;
  50. // 计算目标图片的宽度和高度,以适应最大宽度和高度的要求
  51. let targetWidth = image.width;
  52. let targetHeight = image.height;
  53.  
  54. // 缩放图片尺寸以适应最大宽度和高度
  55. if (targetWidth > maxWidth || targetHeight > maxHeight) {
  56. const scaleFactor = Math.min(
  57. maxWidth / targetWidth,
  58. maxHeight / targetHeight
  59. );
  60. targetWidth *= scaleFactor;
  61. targetHeight *= scaleFactor;
  62. }
  63. // 设置画布的尺寸
  64. canvas.width = targetWidth;
  65. canvas.height = targetHeight;
  66. // 清空画布并在画布上绘制压缩后的图片
  67. context.clearRect(0, 0, targetWidth, targetHeight);
  68. context.drawImage(image, 0, 0, targetWidth, targetHeight);
  69. // 将压缩后的图片数据转换为 data URI。可以使用 type 参数其类型,默认为 PNG 格式。qualitys越小,文件体积越小
  70. const canvasURL = canvas.toDataURL(mimeType, qualitys);
  71. // 解码 data URI,获取图片的二进制数据。atob:是ascii to binary,用于将ascii码解析成binary数据,即Base64的解码过程。
  72. const buffer = atob(canvasURL.split(",")[1]);
  73. let length = buffer.length;
  74. //创建一个 Uint8Array 类型的向量,用于存储图片的二进制数据
  75. const bufferArray = new Uint8Array(new ArrayBuffer(length));
  76. while (length--) {
  77. bufferArray[length] = buffer.charCodeAt(length);
  78. }
  79. // 创建一个压缩后的文件对象
  80. const miniFile = new File([bufferArray], file.name, {
  81. type: mimeType,
  82. });
  83.  
  84. // 解析压缩后的文件对象
  85. resolve({
  86. uid: file.uid,
  87. raw: miniFile,
  88. origin: file,
  89. beforeSrc: target?.result,
  90. afterSrc: canvasURL,
  91. beforeKB: Number((file.size / 1024).toFixed(2)),
  92. afterKB: Number((miniFile.size / 1024).toFixed(2)),
  93. });
  94. };
  95. // 设置图片的 src,触发图片加载
  96. image.src = target?.result;
  97. };
  98. // 读取文件内容,并在读取完成后触发 onload 事件
  99. reader.readAsDataURL(file);
  100. // }
  101. });
  102. }
  103. }

页面使用:
1、组件中引入封装的方法

2、在页面中直接使用方法就 OK,传入一个文件对象,不传第二个值就是默认值

结合 element -Plus组件库,压缩图片大小,限制图片格式的更多相关文章

  1. 转-android图片降低图片大小保持图片清晰的方法

    http://i.cnblogs.com/EditPosts.aspx?opt=1 android里面对于图片的处理一直是个比较烦人的问题,烦人之处在于一个不小心,就有可能造成OOM. 最近碰到一个关 ...

  2. 16款优秀的Vue UI组件库推荐

    16款优秀的Vue UI组件库推荐 Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司的Web前端项目开发中,多个项目采用基 ...

  3. [转载]前端——实用UI组件库

    https://www.cnblogs.com/xuepei/p/7920888.html Angular UI 组件 ngx-bootstrap 是一套Bootstrap 组件 官网:https:/ ...

  4. java关于图片处理修改图片大小

    最近做了一个关于图片浏览的内容.因为图片都是一些证件的资料的扫描件所以比较大,对系统的影响也是非常之大的,有很大可能直接把系统干死.那么我是这么处理的,给大家分享一下.如果大家有好的方案的话一定要早点 ...

  5. 强烈推荐优秀的Vue UI组件库

    Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司的Web前端项目开发中,多个项目采用基于Vue的UI组件框架开发,并投入正 ...

  6. Vue UI组件库

    1. iView UI组件库  iView官网:https://www.iviewui.com/ 2.Vux UI组件库   Vux官网:https://vux.li/ 3.Element UI组件库 ...

  7. ui组件库

    基于Vue的Quasar Framework 中文网 http://www.quasarchs.com/ quasarframework/quasar: Quasar Frameworkhttps:/ ...

  8. 【转】优秀的Vue UI组件库

    原文来源:https://www.leixuesong.com/3342 Vue 是一个轻巧.高性能.可组件化的MVVM库,API简洁明了,上手快.从Vue推出以来,得到众多Web开发者的认可.在公司 ...

  9. [转]使用 Angular CLI 和 ng-packagr 构建一个标准的 Angular 组件库

    使用 Angular CLI 构建 Angular 应用程序是最方便的方式之一. 项目目标 现在,我们一起创建一个简单的组件库. 首先,我们需要创建一个 header 组件.这没什么特别的,当然接下来 ...

  10. Python脚本:删除文件夹下的重复图片,实现图片去重

    近期在整理相册的时候,发现相册中有许多重复图片,人工一张张筛查删除太枯燥,便写下这个脚本,用于删除文件夹下重复的图片. 第一部分:判断两张图片是否相同 要查找重复的图片,必然绕不开判断两张图片是否相同 ...

随机推荐

  1. 解决 wg-quick 在 Mac 上 bash 3 无法运行的问题

    问题原因 我可以理解,开发人员不想使用苹果使用的旧bash v3.但从用户的帖子来看,安装一个较新的bash并不那么好 所以我看了wireguard的wg-quick.需要支持的唯一变化,两个bash ...

  2. mpi转以太网连接300PLC无需编程与1200PLC数据交换

    300PLC转以太网无需编程300PLC通过 NetDevice与1200PLC数据交换 应用概述: 兴达易控MPI转以太网模块MPI-ETH-XD1.0PLUS 通讯模块实现PLC无需编程通过简单的 ...

  3. SonarQube系列-认证&授权的配置

    参考文档:https://docs.sonarqube.org/latest/instance-administration/security/ 概述 SonarQube具有许多全局安全功能: 认证和 ...

  4. oracle 问题:ORA-28040:没有匹配的验证协议

    Oracle11g客户端连接Oracle12C服务器端,需配置项 前置条件:已安装Oracle11g客户端,配置好环境变量,用PL/SQL Developer登录数据库 出现问题:登录数据库时,提示& ...

  5. 在Docker下一键安装部署免费开源的问答社区!

    在Docker下一键安装部署免费开源的问答社区!   1.准备一台VPS主机,没有的话,[搞一台] 2.一键安装部署Docker wget https://raw.githubusercontent. ...

  6. gitbook在线记事本

    https://app.gitbook.com/ About this template: An Internal Wiki to lay out everything anyone needs to ...

  7. 2023_10_09_MYSQL_DAY_01_课后题

    2023_10_09_MYSQL_DAY_01_课后题 #第三章 #1. 查询每名员工的员工姓名,入职时间. SELECT ename, hiredate FROM emp; #2. 查询部门表中部门 ...

  8. 数据链路层传输协议(点到点):停等协议、GBN、SR协议

    数据链路层的传输协议:停等协议.GBN.SR 停止等待协议(单窗口的滑动窗口协议) 滑动窗口协议:GBN.SR GBN协议 GBN发送方需响应的三件事 1. 上层调用(网络层) 上层要发送数据时,发送 ...

  9. 洛谷1451(BFS)

    #include"bits/stdc++.h" using namespace std; int mp[110][110]; bool vis[110][110]; int dx[ ...

  10. CF48C [The Race]

    Problem 题目简述 现有 \(n\) 个已经加过油的加油站,如果当前剩余油量 \(< 10\) 升,则会加 \(x\) 升的油. 初始状态下,有 \(x\) 升油.每个加油站之间的距离为 ...