前端性能优化:使用Vue3+TS+Canvas对图片进行压缩后再上传,优化带宽,减小服务器存储成本,减少流量损耗

news/2024/9/18 13:31:03/ 标签: 前端, 性能优化, vue3, 图片压缩处理
在上传图片之前,对图片进行压缩。看到这里是不是有点懵,前端怎么压缩图片呢,这不应该是后端做的吗?
但是我在开发的时候接到了这样一个需求,要求对用户上传的图片进行一定的压缩,而且并且尽量还原图片的清晰度。
那么对图片上传进行一个压缩的好处在哪里
  1. 提升用户体验
    • 减少图片加载时间,加快页面渲染速度。
    • 对于移动设备来说尤为重要,可以减少流量消耗。
  2. 节省服务器资源
    • 减小上传文件的大小,降低服务器存储成本。
    • 减轻服务器处理图片的压力。
  3. 优化网络传输
    • 在带宽有限的情况下,压缩后的图片可以更快地传输到服务器端。
坏处呢

显而易见,加大工作量,当然,图片也有可能会变得比较模糊(这也是我们要处理的)

本来开发没有引入任何的库,纯手写

使用技术栈为Vue3+Ts+Canvas

再开始之前需要了解部分前置知识,关于图片压缩的类型,压缩时我们会把图片的类型修改为**“image/jpeg”**,为什么呢?

JPEG(Joint Photographic Experts Group)是一种广泛使用的有损压缩图像格式,适用于照片和其他具有丰富色彩和细节的图像。JPEG 格式的主要优点是它能够提供高质量的图像同时保持较小的文件大小,这对于网络传输和存储来说是非常重要的。
兼容性:JPEG 格式在大多数浏览器和设备上都得到了很好的支持。
文件大小:JPEG 可以通过调整质量因子来控制输出文件的大小,这使得它非常适合在网络上传输。
颜色和细节:对于包含大量颜色和细节的照片来说,JPEG 通常能够提供足够的视觉质量。
质量参数:quality 参数只对某些格式有效,如 JPEG。这里使用 "image/jpeg" 可以确保 quality 参数被正确应用。

接下来就开始我们的编码,具体注释,案例,实现都在代码中有所解释

页面,引入的arco-design组件库的上传组件
<template><div><a-upload:auto-upload="false"ref="uploadRef"@change="fileChange"multipledraggable></a-upload></div>
</template>
逻辑
<script setup lang="ts">
let fileNum = 0;
const fileChange = async (files) => {let file = files[fileNum].file;console.log(file, "压缩之前");// 用户还可能传其他的,只压缩图片,并且太小的图片都不进行处理if (file.type.includes("image") && file.size >= 102400) {file = await imageZip(file, 800, 600, 0.8);}console.log(file, "压缩之后");//这里书写你的上传逻辑,根据自身的接口来上传
};const imageZip = (file: File, maxWidth: number,maxHeight: number,quality: number) => {return new Promise((resolve, reject) => {const reader = new FileReader();// 使用readAsDataURL方法十分适合用来读取图片文件,并将其转换为Base64编码的Data URL格式。reader.readAsDataURL(file);// 此时再使用reader.onload事件处理器,对图片进行处理reader.onload = function (event) {const img = new Image();// 将base64的值赋值给img以便后续处理img.src = event.target.result;img.onload = function () {let width = img.width;let height = img.height;// 这里是对图片做宽高自适应if (width > maxWidth) {height *= maxWidth / width;width = maxWidth;}if (height > maxHeight) {width *= maxHeight / height;height = maxHeight;}// 创建一个Canvasconst canvas = document.createElement("canvas");canvas.width = width;canvas.height = height;const ctx = canvas.getContext("2d");/**img: 要绘制的 Image 对象。0: 目标位置的 x 坐标。0: 目标位置的 y 坐标。width: 绘制的宽度。height: 绘制的高度。*/ctx.drawImage(img, 0, 0, width, height);// 直接使用canvas.toBlob()来创建压缩后的Blob对象//canvas.toBlob((blob) => {const files = new File([blob], file.name, { type: file.type });resolve(files);},//指定类型,原因前面也解释了"image/jpeg",// 控制质量,越小图片体积就越小,当然也会更加模糊quality);};};});
};
</script>

我专门写了一个后台,来看图片的体积变化,总结:越大的图片压缩后,体积变化越大,同时后台查看图片也没有丢失精度
在这里插入图片描述


http://www.ppmy.cn/news/1519821.html

相关文章

vue项目中scss文件导出,js文件引入scss文件时为空{}

解决办法一&#xff1a; 将scss文件重命名为 ‘原名.module.scss’ 解决办法二&#xff1a;降低vue脚手架的版本 "vue/cli-plugin-babel": "~4.5.0", "vue/cli-plugin-eslint": "~4.5.0", "vue/cli-service": "~4.5.0…

二十五、go语言的通道

目录 一、收发通信 二、将通道作为参数传递&#xff08;读、写、读写&#xff09; 三、select 1、先收到消息的先执行 2、一直没有收到消息退出通道 3、不知道何时退出情况下退出通道 go语言中的goroutine可以看成线程&#xff0c;但是又不能看成和其它语言一样的线程&am…

【Kubernetes知识点问答题】Namespace(命名空间)

目录 1. 什么是 K8s 的 namespace&#xff1f; 2. 系统默认创建了哪几个 namespace&#xff1f; 1. 什么是 K8s 的 namespace&#xff1f; 在 K8s 中&#xff0c; Namespace&#xff08;命名空间&#xff09;提供了一种机制&#xff0c;将同一集群中的资源划分为相互隔离的组…

c# net8调用vc写的dll

dll程序&#xff08;vc,x86) 头文件 extern "C" int __declspec(dllexport) WINAPI add(int a, int b);实现 int WINAPI add(int a, int b) {return a b; }c#/net8 函数声明&#xff1a; [DllImport("dll/Dll1.dll", CallingConvention CallingCo…

Git 提交代码注释信息规范

在团队协作开发过程中&#xff0c;规范的 Git 提交信息不仅能提高代码维护的效率&#xff0c;还能让其他开发者更容易理解每次提交的目的和内容。下面是常用的 Git 提交信息类型及其详细说明。此外&#xff0c;还包括一些额外的提交类型&#xff0c;以便更全面地覆盖开发过程中…

线程池相关知识点

线程池是什么相信大家都是知道的&#xff0c;所以这里就不做解释了&#xff0c;直接看相关知识点吧。 初始化线程池方法 继承ThreadPool 实现Runnable 实现Callable 接口 FutureTask &#xff08;可以拿到返回结果&#xff0c;可以处理异常&#xff09; 核心参数 corePoo…

将string类中能够实现的操作都封装在MyString类中

包括&#xff1a; 构造函数 析构函数 重载 &#xff0c;[]&#xff0c;,,,!,<,>,<,>,<<,>>; at&#xff1b; data&#xff1b; c_str; empty; length; capasityacity; clear; push_back; pop_back; append; 程序中我封装了大部分&#…

el-time-select 动态增加时间

<template><div><div v-for"(item, index) in timeSlots" :key"index"><el-time-select placeholder"起始时间" v-model"item.startTime" :picker-options"{start: 00:00,step: 00:15,end: 23:59,}"&g…

语音控制开关的语音识别ic芯片方案

语音控制开关是一种基于语音识别技术的设备&#xff0c;它通过内置的语音识别芯片&#xff0c;将用户的语音指令转化为电信号&#xff0c;从而实现对设备的控制。例如在智能家居设备上的应用&#xff0c;通常需要连接到家庭的Wi-Fi网络上&#xff0c;以便与智能手机或智能音箱等…

用实时计算释放当下企业大数据潜能

摘要&#xff1a;本文整理自阿里云高级产品解决方案架构师王启华&#xff08;敖北&#xff09;老师在 Flink Forward Asia 2023 中闭门会的分享。内容分为以下四个部分&#xff1a; 业务需求变化推动架构演进实时计算对于企业生产的意义从技术架构和技术场景来看发展和迭代客户…

使用 streamlink 把 m3u8 转为 mp4

问题描述&#xff0c; 背景&#xff0c; 来源&#xff1a; 下载 m3u8 ts —> 转为mp4, 按照以往的做法&#xff0c; 就是使用 python requests 一步一步地下载 m3u8, ts&#xff0c; 然后转换。 但是个人写的东西&#xff0c;毕竟问题比较多。 而且&#xff0c; 但是&…

2024 年的 Web3 游戏:演变、趋势和市场动态

Web3 游戏行业在经历了多年的快速发展和变革之后&#xff0c;正在2024年迎来全新的阶段。这个行业从最初的边玩边赚&#xff08;Play-to-Earn, P2E&#xff09;模式出发&#xff0c;如今正在向更为平衡的“边玩边赚”模式转型。这种转型不仅解决了早期 P2E 模式下存在的可持续性…

MyBatis-SQL-语句执行流程

已查询为例 首先我们可以看到&#xff0c;在查询的时候Mapper对象已经是被代理过后的&#xff1a; 所以会执行invoke方法&#xff0c;其底层实现就是JDK的动态代理&#xff1a; 如下图所示&#xff0c;如果MethodCache里面存在方法&#xff0c;则判断这个方法是否为default方…

python实现人工神经网络

要编写一个简单的人工神经网络&#xff08;ANN&#xff09;程序&#xff0c;可以从一个基本的前馈神经网络开始&#xff0c;该网络通常包括输入层、一个或多个隐藏层以及输出层。在这个例子中&#xff0c;将使用Python的NumPy库来处理数学运算&#xff0c;并使用Sigmoid函数作为…

【Python批量下载Landsat数据】

批量下载Landsat数据&#xff08;例如Landsat 8 OLI/TIRS&#xff09;可以通过多种方法实现&#xff0c;但通常涉及使用在线服务或API接口&#xff0c;如USGS EarthExplorer、Google Earth Engine&#xff08;GEE&#xff09;或者专门的库如landsatxplore&#xff08;一个Pytho…

配置了680M和780M集显的AMD CPU列表

AMD Radeon 680M 核显配置在以下型号的 CPU 上面&#xff1a; - Ryzen 9 6980HX&#xff1a;8 核心 16 线程&#xff0c;最高加速时钟频率可达 5.0GHz&#xff0c;配备 12CU RDNA 2 架构的 Radeon 680M 核显&#xff0c;频率为 2.4GHz 。 - Ryzen 9 6900HX&#xff1a;8 核心 …

MAC环境导出项目的目录结构

一、安装Homebrew包管理工具 /bin/bash -c "$(curl -fsSL https://gitee.com/ineo6/homebrew-install/raw/master/install.sh)" 官网网址&#xff1a;https://brew.idayer.com/ 二、用brew包管理工具安装tree brew install tree 三、打开终端&#xff0c;导出项目…

深入Redis:细谈持久化

Redis的数据是保存在内存中的&#xff0c;内存里面的数据是不持久的&#xff0c;要想做到持久化&#xff0c;必须要把在内存中的数据储存到硬盘上。 Redis速度非常快&#xff0c;数据只有在内存中才有这样的速度&#xff0c;但是为了持久&#xff0c;数据还是要想办法保存到硬…

Java Excel转PDF(免费)

目前市面上 Excel 转 PDF 的组件较多&#xff1a; 收费&#xff1a;aspose、GcExcel、spire开源&#xff1a;jacob、itextpdf 其中收费的组件封装得比较好&#xff0c;代码简洁&#xff0c;转换的效果也很好&#xff0c;但收费也高得离谱&#xff1a; 为了成本考虑&#xff…

videojs宫格视频选择播放

项目需要四宫格播放视频&#xff0c;而且还要实现点击视频加入播放。 首先&#xff0c;肯定要实现再一个页面上显示多个视频源并播放视频&#xff1a; <template><div><div v-for"(item,index) in videoList" :key"index" class"te…