前端图片压缩上传,减少等待时间!优化用户体检

添加图片注释,不超过 140 字(可选)
这里有两张图片,它们表面看上去是一模一样的,但实际上各自所占用的内存大小相差了180倍。

添加图片注释,不超过 140 字(可选)

添加图片注释,不超过 140 字(可选)
可以看到右边的图片是22.3MB,而左侧的图片只有127KB,但是实际上这两张图片的大小都是22.3MB。
最近在开发中遇到这样的一个需求,需要把用户上传的图片先进行一次压缩,然后再保存到服务器,这里我们除了优先考虑压缩图片的大小外,还要顾及图片压缩后的清晰度问题。

添加图片注释,不超过 140 字(可选)
经过对比,图片并没有明显的失真情况,下面给大家分享一下,我的解决方法:
这里我采用element的文件上传控件来上传图片
<el-uploadclass="avatar-uploader":action="GLOBAL.serverFileUrl"name="file"drag:show-file-list="false":on-change="beforeAvatarUpload"><i class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
定义了三个事件方法
//图片上传之前处理事件beforeAvatarUpload(file) {console.log(file);const isJpgPng =file.raw.type === "image/jpeg" || file.raw.type === "image/png";if (!isJpgPng ) {this.GLOBAL.messageEvent("error","上传头像图片只能是 JPG/PNG 格式!");} else {this.compressImg(file.raw);}return isJpgPng;},
compressImg(file) {let that = this;// ?通过FormData构造函数创建一个空对象let formData = new FormData();let reader = new FileReader();// ?将读取到的文件编码成DataURLreader.readAsDataURL(file);// ?压缩图片reader.onload = function(ev) {try {// ?读取图片来获得上传图片的宽高let img = new Image();img.src = ev.target.result;img.onload = function(ev) {// ?将图片绘制到canvas画布上进行压缩let canvas = document.createElement("canvas");let context = canvas.getContext("2d");let imgwidth = img.width;let imgHeight = img.height;// ?按比例缩放后图片宽高;let targetwidth = imgwidth;let targetHeight = imgHeight;// ?/如果原图宽大于最大宽度if (targetWidth > targetHeight) {// ?原图宽高比例let scale = targetHeight / 1280;targetHeight = 1280;targetWidth' = targetwidth / scale;} else {// ?原图宽高比例let scale = targetWidth / 1280;targetWidth = 1280;targetHeight = targetHeight / scale;}// ?缩放后高度仍然大于最大高度继续按比例缩小canvas.width = targetwidth; //canvas的宽=图片的宽canvas.height = targetHeight; //canvas的高=图片的高context.clearRect(0,0, canvas.width, canvas.height);context.drawImage(this, 0, 0, canvas.width, canvas.height);let data = "":// ?如果图片小于0.6Mb,不进行压缩,并返回二进制流if (file.size <= 628288) {data = canvas.toDataURL("image/jpeg");formData.append("file", file);that.handleChange(file);}// ?如果图片大于e.6Mb,进行压缩,并返回二进制流else {// todo 压缩文件大小比例data = canvas.toDataURL("image/jpeg",0.4);let paper = that.GLOBAL.dataURLtoFile(data, file.name);formData.append("file", paper);that.handleChange(paper);}};} catch (error) {console.log("出现错误",error);}};},
// todo 调用上传接口 文件提交给后台handleChange(file) (let formData = new FormData( );formData.append("file",file.raw || file);console.log(formData);brandServices.uploadFile(formData).then(res => {if (res.data.errno === 0) {this.imgUrl = res.data.data;this.dialogImageUrl = URL.createObjectURL(file);this.GLOBAL.messageEvent("success",res.data.message);} else { this.GLOBAL .messageEvent("error",res .data.message);}});}
总结:
先进行图片上传前的验证;接着再对图片实现压缩的操作;最后就可以把文件流提交给后台。
具体的思路是:通过FormData构造函数创建一个空对象,将图片绘制到canvas画布上,然后再进行压缩。用户上传的文件超过一定的大小后就可以执行压缩的操作,当然如果图片太小的话,我们就没必要再压了。建议采用宽高等比例的方式来压缩,不然可能会出现图片变形的情况。
相关文章:
前端图片压缩上传,减少等待时间!优化用户体检
添加图片注释,不超过 140 字(可选) 这里有两张图片,它们表面看上去是一模一样的,但实际上各自所占用的内存大小相差了180倍。 添加图片注释,不超过 140 字(可选) 添加图片注释&…...
Ionic header content footer toolbar UI实例
1 ionic的button图标 <ion-header [translucent]"true"><ion-toolbar><ion-buttons slot"start"><ion-back-button default-href"/tabs/tab1" text"back" icon"caret-back"></ion-back-button&…...
uniapp 解决H5跨域的问题
uniapp 解决h5跨域问题 manifest.json manifest.json文件中,点击“源码视图”,在此对象的最后添加以下代码: "h5" : {"devServer" : {"port" : 8080, //端口号"disableHostCheck" : true,"proxy" :…...
对称加密(symmetric encryption)和非对称加密(Asymmetric Encryption)(密钥、公钥加密、私钥解密)AES、RSA
文章目录 对称加密与非对称加密对称加密1.1 定义1.2 工作原理1.3 场景分析1.4 算法示例(以AES为例)1.5 对称加密的优点与缺点优点缺点 非对称加密2.1 定义2.2 工作原理注意:每次生成的RSA密钥对都会不一样 2.3 场景分析2.4 算法示例ÿ…...
iOS 16.4 之后真机与模拟器无法使用Safari调试H5页面问题
背景 iOS 16.4之后用真机调试H5时候发现,Safari中开发模块下面无法调试页面 解决方案 在WKWebView中设置以下代码解决 if (available(iOS 16.4, *)) {[_webView setInspectable:YES];}然后再次调试就可以了...
野火霸天虎 STM32F407 学习笔记_3 尝试寄存器映射方式点亮 LED 灯
新建工程 寄存器方式 要命啊,一看名字我就不想试。寄存器新建不得麻烦死。 哎算了为了学习原理,干了。 我们尝试自己写一个寄存器的库函数来引用。 首先我们需要引用 st 官方启动文件 stmf4xx.s,具体用途后面章节再展开讲解。然后我们自…...
ZZ308 物联网应用与服务赛题第F套
2023年全国职业院校技能大赛 中职组 物联网应用与服务 任 务 书 (F卷) 赛位号:______________ 竞赛须知 一、注意事项 1.检查硬件设备、电脑设备是否正常。检查竞赛所需的各项设备、软件和竞赛材料等; 2.竞赛任务中所使用…...
怎样选择文件外发控制系统,让数据实现高效安全交换?
制造型企业都非常重视其知识产权(IP)的安全性,尤其是其最有价值的产品设计数据的安全问题。基于复杂的供应链生态,每天可能要与几十家甚至上百家供应商及合作伙伴进行数据交换。不管是一级还是二级供应商,合作伙伴还是…...
专访 SPACE ID:通往 Web3 无许可域名服务协议之路
Web3 行业发展风起云涌,对于初创项目而言,如何寻找适合自己的赛道是首要问题。当前伴随用户交互和跨平台操作需求日渐兴起,如何更迅速地使用一站式域名实现便捷验证成为大众的心头期盼。 这一背景下,SPACE ID 于众星林立的 Web3 …...
合并分支--将自己的分支合并到master分支
在版本控制系统(例如Git)中,将自己的分支合并到master(或者主分支)通常需要以下步骤: ### 1. 切换到主分支 首先,确保你的本地仓库当前处于主分支。你可以使用以下命令切换到主分支࿱…...
力扣:153. 寻找旋转排序数组中的最小值(Python3)
题目: 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums [0,1,2,4,5,6,7] 在变化后可能得到: 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]若旋转…...
matlab中实现画函数图像添加坐标轴
大家好,我是带我去滑雪! 主函数matlab代码: function PlotAxisAtOrigin(x,y); if nargin 2 plot(x,y);hold on; elsedisplay( Not 2D Data set !) end; Xget(gca,Xtick); Yget(gca,Ytick); XLget(gca,XtickLabel); YLget(gca,YtickLabel)…...
C语言求解一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
完整代码: /* 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问 该数是多少?*/ #include<stdio.h>int main(){//num为最终所求那个数int num;//i*i为第一个完全平方数for (int i 10; …...
AtCoder abc148
C题 求GCD D题 顺序遍历 E题 trailing zero只与5的个数有关,因此算一下5/25/125…的倍数 # -*- coding: utf-8 -*- # time : 2023/6/2 13:30 # file : atcoder.py # software : PyCharmimport bisect import copy import sys from itertools import perm…...
k8s、docker 卸载
k8s卸载 k8s 重置 kubeadm reset -f如果kubernets是1.24以上版本,请先单独卸载containerd sudo apt purge containerd.iok8s软件卸载 ubuntu #apt卸载 apt purge kubelet kubeadm kubectlcentos yum erase -y kubelet kubectl kubeadm 删除kubelet相关信息&am…...
【Linux】Shell命令行的简易实现(C语言实现)内键命令,普通命令
文章目录 0.准备工作1.大体框架 一、获取命令行二、解析命令行三、进程执行1.普通命令2.内建命令 四、完整代码: 0.准备工作 1.大体框架 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <u…...
Kafka -- 架构、分区、副本
1、Kafka的架构: 1、producer:消息的生产者 2、consumer:消息的消费者 3、broker:kafka集群的服务者,一个broker就是一个节点,主要是负责处理消息的读、写的请求和存储消息。在kafka cluster中包含很多的br…...
CSS特效001:鼠标放div上,实现旋转、放大、移动等效果
GPT能够很好的应用到我们的代码开发中,能够提高开发速度。你可以利用其代码,做出一定的更改,然后实现效能。 css实战中,经常会看到这样的场景,鼠标放到一个图片或者一个div块状时候,会出现旋转、放大、移动…...
gin 快速入门手册
文章目录 安装URL和路由分组2. 带参数的url3. 获取路由分组的参数 获取参数1. 获取get参数2. 获取post参数3. get、post混合 JSON 、 ProtoBuf渲染1. 输出json和protobuf2. PureJSON 表单验证1. 表单的基本验证 中间件和next函数1. 无中间件启动2. 使用中间件3. 自定义组件 设置…...
Window下安装 Mongodb,并实现单点事务
在window操作系统下安装Mongodb,并让单点mongodb支持事务,mongodb5以上时才支持事务,所以必须时mongodb5及以上版本才支持。 1、下载mongodb安装文件 (1) 下载mongodb msi 安装文件 地址:mongocommunity &…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
