文章の目录

  • 问题产生背景
  • 解决办法
    • 1、使用纯 js 解决
    • 2、插件 js-image-compressor
  • 写在最后

问题产生背景

在某一h5的项目,要求上传的图片格式为 base64 , 问题是用户上传的图片基本都在MB 级别,转base64 以后,图片的体积会增大30%以上,随着图片的体积增加,转换的base64 格式文件体积越大,如果此时前端不对用户上传的图片体积进行压缩,可能会导致服务器压力过大,从而崩溃;

解决办法

1、使用纯 js 解决

解决思路:
1、通过 input 文件选择框拿到要上传的图片文件file
2、FileReader.readAsDataURL() 读取 file 内容。完成后 result 属性中将包含一个 data: URL格式的 Base64字符串以表示所读取文件的内容。
3、创建一个 img 标签,将 FileReader 对象返回的 base64 格式 url 给到一个 img 标签
4、img.onload() 函数中获取图片的尺寸,再通过 canvas.drawImage() 绘制图像,设置尺寸或者图像的质量等
canvas.toDataURL(file.type, quality) 设置图像的质量,将 canvas 转换为图片 base64 格式
代码如下所示:

compressImg(file) {const reader = new FileReader();// readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE,并触发 loadend (en-US) 事件,// 同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。reader.readAsDataURL(file);reader.onload = () => {const img = new Image();img.src = reader.result;img.onload = () => {// 图片的宽高const w = img.width;const h = img.height;const canvas = document.createElement("canvas");// canvas对图片进行裁剪,这里设置为图片的原始尺寸canvas.width = w;canvas.height = h;const ctx = canvas.getContext("2d");// canvas中,png转jpg会变黑底,所以先给canvas铺一张白底ctx.fillStyle = "#fff";// fillRect()方法绘制一个填充了内容的矩形,这个矩形的开始点(左上点)在// (x, y) ,它的宽度和高度分别由width 和 height 确定,填充样式由当前的fillStyle 决定。ctx.fillRect(0, 0, canvas.width, canvas.height);// 绘制图像ctx.drawImage(img, 0, 0, w, h);// canvas转图片达到图片压缩效果// 返回一个包含图片展示的 data URI base64 在指定图片格式为 image/jpeg 或 image/webp的情况下,// 可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。const dataUrl = canvas.toDataURL("image/jpeg", 0.8);// base64格式文件转成Blob文件格式return blobFile = dataURLtoBlob(dataUrl);// 拿到这个blobFile文件就可以上传给服务端console.log("压缩后的file----------", blobFile);};};
}// canvas生成的格式为base64,如果需要Blob格式可按如下进行转化dataURLtoBlob(dataurl) {const arr = dataurl.split(","),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]);let n = bstr.length;const u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new Blob([u8arr], { type: mime });},

使用以上方法存在缺点:

  • 压缩后的格式只能是 jpeg 格式,如果需要其他格式的可能需要优化或者用别的方法

2、插件 js-image-compressor

在使用中,我们可以根据自身需求自定义配置压缩比(quality)、输出图片类型(mimeType)、宽(width)、高(height)、最大宽(maxWidth)、最大高(maxHeight)、最小宽(minWidth)、最大高(minHeight)、png转jpeg阈值(convertSize)、是否矫正jpeg方向(redressOrientation)和是否宽松模式(loose)。
● 是否矫正jpeg方向(redressOrientation),jpeg 格式图片在某些iOS浏览器会按其方向呈现图像,这个选项可以控制恢复初始方向,默认为 true;
● 是否宽松模式(loose)、的意思是控制当压缩的图片 size 大于源图片,输出源图片,否则输出压缩后图片,默认是 true。
以下是标准配置:

var options = {file: file,quality: 0.6,mimeType: 'image/jpeg',maxWidth: 2000,maxHeight: 2000,width: 1000,height: 1000,minWidth: 500,minHeight: 500,convertSize: Infinity,loose: true,redressOrientation: true,// 压缩前回调beforeCompress: function (result) {console.log('压缩之前图片尺寸大小: ', result.size);console.log('mime 类型: ', result.type);},// 压缩成功回调success: function (result) {console.log('压缩之后图片尺寸大小: ', result.size);console.log('mime 类型: ', result.type);console.log('实际压缩率: ', ((file.size - result.size) / file.size * 100).toFixed(2) + '%');},// 发生错误error: function (msg) {console.error(msg);}
};
new ImageCompressor(options);

以上就是插件式的解决办法,更详细的文档,可以在 gitbhub 的官方文档上查看;插件式解决办法已经在项目中实践,推荐大家使用~~

写在最后

以上提供的插件式解决办法已经在项目中实践,但是存在的问题是,插件控制的压缩率和实际的压缩率有一定的出入(不同格式的图片出入有一定差异),因此压缩率不好严格控制,有更好解决办法的朋友欢迎评论区交流;

前端图片压缩解决办法相关推荐

  1. 移动前端—图片压缩上传实践

    在做移动端图片上传的时候,用户传的都是手机本地图片,而本地图片一般都相对比较大,拿iphone6来说,平时拍很多图片都是一两M的,如果直接这样上传,那图片就太大了,如果用户用的是移动流量,完全把图片上 ...

  2. 前端图片压缩上传(纯js的质量压缩,非长宽压缩)

    前端图片压缩上传(纯js的质量压缩,非长宽压缩) 此demo为大于1M对图片进行压缩上传 若小于1M则原图上传,可以根据自己实际需求更改. demo源码如下: <!DOCTYPE html> ...

  3. 前端安全问题及解决办法

    前端安全问题及解决办法 参考文章: (1)前端安全问题及解决办法 (2)https://www.cnblogs.com/superSmile/p/8039451.html 备忘一下.

  4. html背景图片拉伸解决办法

    html背景图片拉伸解决办法 body {background-size: 100% 100%; //关键代码,直接拉伸背景图background-image: url("img/99.jp ...

  5. php怎么显示不了图片,php显示不了图片的解决办法,

    php显示不了图片的解决办法PHP不能显示图片的解决方案,Php不能显示图片,因为源代码中除了img输出还有其他输出.解决方法是在调用头之前取消任何输出. 推荐: <PHP视频教程> 具体 ...

  6. JS前端图片压缩上传

    JS前端图片压缩上传重点知识 最近在做一个手机端的图片上传,写了一个比较符合自己要求的方法,可供参考 在做这个功能模块时,我遇到了以下问题,都花费了大量时间: 1. 不知道怎么压缩图片,(代码和方法) ...

  7. docx转doc时,防止公式被转成图片的解决办法

    [转载]docx转doc时,防止公式被转成图片的解决办法 编辑社回复需要doc(Word 97-2003)格式的文档,可是将docx(Word 2007+)另存为doc格式时,发现公式被转成了图片.其 ...

  8. 前端图片压缩上传(压缩篇)

    为什么说这是一篇比较适合小白的前端图片压缩文章呢?因为我也是一个刚工作半年的前端小白,最近接到了一个前端图片压缩上传的任务,通过各种百度博客完成了这项任务,但是任务完成后对各种技术细节却还不是特别理解 ...

  9. Win7/windows8/win 10系统下Photoshop不能直接拖拽打开图片的解决办法

    我们知道Adobe Photoshop打开图片的方式有很多种,其中有一种是我们经常用到的,那就是直接从资源管理器或者其他地方中直接把图片通过拖拽的方式拖到PS窗口中打开,在Win10系统中,使用PS的 ...

最新文章

  1. python3安装setuptools步骤_setuptools、pip的安装
  2. vivado烧录flash过程
  3. 【资源】100+本数据科学电子书
  4. MySQL安装失败问题汇总
  5. ffmpeg解码器优化
  6. 你好,面试官 | 你觉得MySQL自增主键连续吗?
  7. Multi_thread--Linux下多线程编程互斥锁和条件变量的简单使用
  8. 微软面试题 麻将胡牌算法
  9. photoshop第九章:文字和场景效果的制作
  10. 道指30只成分股的股价及历史股价抓取分析
  11. 15个提高编程技巧的JavaScript工具
  12. 阿里云对象存储上传或复制文件时报The request signature we calculated does not match the signature you provided...
  13. 腾讯qq的授权管理查看页面
  14. python把数据生成图表_python从Oracle读取数据生成图表
  15. Simulink基础【1】-弹簧-阻尼模型的常微分方程求解
  16. 夜神模拟器开启网络桥接模式共享局域网ip
  17. mac插网线不能上网_Mac有线无法上网怎么办 苹果更新导致无法有线上网解决办法...
  18. 云模型的介绍及python简单实现
  19. 数据的加载 - 清洗处理 - 分组分类 - 存储
  20. 为什么越来越多博士逃离科研?

热门文章

  1. 苹果mac 远程桌面php开发,如何从苹果电脑MAC系统登录远程桌面
  2. AutocadCAD二维平面作图
  3. Machine learning week 10(Andrew Ng)
  4. java的Debug的使用
  5. 关于台湾通行证及入台证的办理流程(上海版)
  6. 前端开发_HTML5_盒子定位(position)
  7. SpringBoot修改启动时的logo图案
  8. PHP生肖查询顺序错了怎么改,十二生肖的顺序是怎样的?
  9. 数学分析 定积分的应用(第10章)
  10. 深入理解Linux进程管理(1.0)