当前位置:首页 » 《休闲阅读》 » 正文

【vue3】前端上传图片的格式大小限制和压缩

4 人参与  2024年05月24日 13:44  分类 : 《休闲阅读》  评论

点击全文阅读


目录

前言

对上传图片进行格式大小限制

压缩上传图片


前言

上篇文章中研究了如何使用双token机制,在此篇中就暴露了一些问题:当accesstoken过期后,直到拿到最终想要得到的数据,期间需要经历三次请求——第一次请求,拿到accesstoken过期的消息——第二次携带refreshtoken发起请求,刷新了accesstoken——第三次携带新的accesstoken发起请求,拿到数据。在这个过程中会出现如下报错:

 无法加载响应数据:No data found for resource with given identifier.

在测试了一系列的请求之后,发现问题可能是该次请求携带的请求信息过大。因为我们出现问题的请求是前端上传图片到服务端获取图片链接。此时,前端能想到的优化方案是限制用户上传图片的大小和格式,并且对上传图片进行压缩。

对上传图片进行格式大小限制

// 上传图片大小及格式限制export function restrictionPic(file) {  // 定义上传图片大小需小于2MB  const isLt2M = file.size / 1024 / 1024 < 2;  if (!isLt2M) {    ElMessage.error("上传头像图片大小不能超过 2MB!");    return isLt2M;  }  // 定义上传图片格式,  const types = ["image/jpg", "image/png"];  const isType = types.includes(file.type);  if (!isType) {    ElMessage.error("上传头像图片格式不正确!");    return isType;  }}

压缩上传图片

用到的api:

FileReader:FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。

//读取文件的方法const fileToDataURL = (file) => {  return new Promise((resolve) => {    const reader = new FileReader()    reader.onloadend = (e) => resolve(e.target.result)    reader.readAsDataURL(file)  })}

Image():Image()函数将会创建一个新的HTMLImageElement实例,它的功能等价于 ​​​​​document.createElement('img')。

//文件转成图片流const dataURLToImage = (dataURL) => {  return new Promise((resolve) => {    const img = new Image()    img.onload = () => resolve(img)    img.src = dataURL  })}

​​​​​canvas:canvas是一个可以使用脚本 (通常为JavaScript) 来绘制图形的 HTML元素。例如,它可以用于绘制图表、制作图片构图或者制作简单的动画。

// 压缩图片函数,接收一个文件和压缩质量参数export function compressPic(file, quality) {  var qualitys = 0.52  // 根据文件大小设置不同的默认压缩质量  if (parseInt((file.size / 1024).toFixed(2)) < 1024) {    qualitys = 0.85  }  if (5 * 1024 < parseInt((file.size / 1024).toFixed(2))) {    qualitys = 0.92  }  if (quality) qualitys = quality  // 如果上传的是多个文件,递归处理每个文件  if (file[0]) {    return Promise.all(Array.from(file).map(e => this.compressPic(e, qualitys)))  } else {    return new Promise((resolve) => {      // 如果图片大小小于300KB,直接返回原始图片数据      if ((file.size / 1024).toFixed(2) < 300) {        resolve({          file: file        })      } else {        // 创建FileReader对象,异步读取存储在客户端上的文件内容        const reader = new FileReader()        // 读取操作完成时触发该事件,使用格式(必须将接收到的数据从onload发送到其他函数):reader.onload = e => {}        reader.onload = ({          target: {            result: src          }        }) => {          //创建img元素          const image = new Image()          // 图片加载完成后异步执行,当image的src发生改变,浏览器就会跑去加载这个src里的资源,这个操作是异步的。          image.onload = async () => {            // 创建一个新的画布元素和上下文,用于绘制压缩后的图片            const canvas = document.createElement('canvas')            const context = canvas.getContext('2d')            // 计算目标图片的宽度和高度,以适应最大宽度和高度的要求            var targetWidth = image.width            var targetHeight = image.height            var maxWidth = 800            var maxHeight = 800            // 缩放图片尺寸以适应最大宽度和高度            if (targetWidth > maxWidth || targetHeight > maxHeight) {              const scaleFactor = Math.min(maxWidth / targetWidth, maxHeight / targetHeight);              targetWidth *= scaleFactor;              targetHeight *= scaleFactor;            }            // 设置画布的尺寸            canvas.width = targetWidth            canvas.height = targetHeight            // 清空画布并在画布上绘制压缩后的图片            context.clearRect(0, 0, targetWidth, targetHeight)            context.drawImage(image, 0, 0, targetWidth, targetHeight)            // 将压缩后的图片数据转换为 data URI。可以使用 type 参数其类型,默认为 PNG 格式。qualitys越小,文件体积越小            const canvasURL = canvas.toDataURL(file.type, qualitys)            // 解码 data URI,获取图片的二进制数据。atob:是ascii to binary,用于将ascii码解析成binary数据,即Base64的解码过程。            const buffer = atob(canvasURL.split(',')[1])            let length = buffer.length            //创建一个 Uint8Array 类型的向量,用于存储图片的二进制数据            const bufferArray = new Uint8Array(new ArrayBuffer(length))            while (length--) {              bufferArray[length] = buffer.charCodeAt(length)            }            // 创建一个压缩后的文件对象            const miniFile = new File([bufferArray], file.name, {              type: file.type            })            // 解析压缩后的文件对象            resolve({              file: miniFile,              origin: file,              beforeSrc: src,              afterSrc: canvasURL,              beforeKB: Number((file.size / 1024).toFixed(2)),              afterKB: Number((miniFile.size / 1024).toFixed(2))            })          }          // 设置图片的 src,触发图片加载          image.src = src        }        // 读取文件内容,并在读取完成后触发 onload 事件        reader.readAsDataURL(file)      }    })  }}

参考文章:前端图片最优化压缩方案


点击全文阅读


本文链接:http://zhangshiyu.com/post/112858.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 祖母寿宴,侯府冒牌嫡女被打脸了(沈屿安秦秀婉)阅读 -
  • 《雕花锦年,昭都旧梦》(裴辞鹤昭都)完结版小说全文免费阅读_最新热门小说《雕花锦年,昭都旧梦》(裴辞鹤昭都) -
  • 郊区41号(许洛竹王云云)完整版免费阅读_最新全本小说郊区41号(许洛竹王云云) -
  • 负我情深几许(白诗茵陆司宴)完结版小说阅读_最热门小说排行榜负我情深几许白诗茵陆司宴 -
  • 九胞胎孕妇赖上我萱萱蓉蓉免费阅读全文_免费小说在线看九胞胎孕妇赖上我萱萱蓉蓉 -
  • 为保白月光,侯爷拿我抵了债(谢景安花田)小说完结版_完结版小说全文免费阅读为保白月光,侯爷拿我抵了债谢景安花田 -
  • 陆望程映川上官硕《我的阿爹是带攻略系统的替身》最新章节阅读_(我的阿爹是带攻略系统的替身)全章节免费在线阅读陆望程映川上官硕
  • 郑雅琴魏旭明免费阅读_郑雅琴魏旭明小说全文阅读笔趣阁
  • 头条热门小说《乔书意贺宴临(乔书意贺宴临)》乔书意贺宴临(全集完整小说大结局)全文阅读笔趣阁
  • 完结好看小说跨年夜,老婆初恋送儿子故意出车祸_沈月柔林瀚枫完结的小说免费阅读推荐
  • 热推《郑雅琴魏旭明》郑雅琴魏旭明~小说全文阅读~完本【已完结】笔趣阁
  • 《你的遗憾与我无关》宋怀川冯洛洛无弹窗小说免费阅读_免费小说大全《你的遗憾与我无关》宋怀川冯洛洛 -

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1