推荐!开箱即用的前端图片压缩方案(附源码)

boyanx1天前技术教程1

前端实现图片压缩的背景

我们都知道在“寸土寸金”的互联网时代, 速度是第一竞争力, 虽然我们的5G发展已经摇摇领先, 但是也经不住用户在一个网页里传很多“巨无霸”图片, 最终导致的结果就是页面“龟速”打开......

那么作为技术人, 当然也有一堆的解决方案, 比如:

  • 压缩图片再上传
  • 将图片上传到图床, 利用图床压缩能力和CDN节点就近分发
  • 图片流式加载
  • 图片懒加载/ 预加载

当然聪明的小伙伴也会将上面的方案组合, 设计更优秀的图片“提速”方案.

今天不会和大家把所有方案都介绍一遍, 因为网上也有很多实践, 接下来会从前端技术提升的角度, 分享一下如何用原生 javascript, 实现从图片上传图片自定义压缩的完整方案. 大家可以把文章中介绍的方案直接用于自己的实际开发中, 或者基于它设计更棒的图片压缩方案.

实现图片压缩的方案

前端实现图片压缩无非就是在用户上传图片文件后, 将file转换成image对象, 然后再利用canvas 及其 api 将图片压缩成指定体积. 如下流程:

代码实现

首先我们先实现将file转换成image对象, 这里我们用到了FileReader API, 代码如下:

// 压缩前将file转换成img对象
function readImg(file:File) {
    return new Promise((resolve, reject) => {
     const img = new Image()
     const reader = new FileReader()
     reader.onload = function(e:any) {
      img.src = e.target.result
     }
     reader.onerror = function(e) {
      reject(e)
     }
     reader.readAsDataURL(file)
     img.onload = function() {
      resolve(img)
     }
     img.onerror = function(e) {
      reject(e)
     }
    })
}

这里使用 promise 来设计生成图片数据的方法, 接下来我们看看核心的图片压缩源码:

/**
 * 压缩图片
 * @param img 被压缩的img对象
 * @param type 压缩后转换的文件类型
 * @param mx 触发压缩的图片最大宽度限制
 * @param mh 触发压缩的图片最大高度限制
 * @param quality 图片质量
 */
 function compressImg(img: any, type:string, mx: number, mh: number, quality:number = 1) {
    return new Promise((resolve, reject) => {
     const canvas = document.createElement('canvas')
     const context = canvas.getContext('2d')
     const { width: originWidth, height: originHeight } = img
     // 最大尺寸限制
     const maxWidth = mx
     const maxHeight = mh
     // 目标尺寸
     let targetWidth = originWidth
     let targetHeight = originHeight
     if (originWidth > maxWidth || originHeight > maxHeight) {
      if (originWidth / originHeight > 1) {
       // 宽图片
       targetWidth = maxWidth
       targetHeight = Math.round(maxWidth * (originHeight / originWidth))
      } else {
       // 高图片
       targetHeight = maxHeight
       targetWidth = Math.round(maxHeight * (originWidth / originHeight))
      }
     }
     canvas.width = targetWidth
     canvas.height = targetHeight
     context?.clearRect(0, 0, targetWidth, targetHeight)
     // 图片绘制
     context?.drawImage(img, 0, 0, targetWidth, targetHeight)
     canvas.toBlob(function(blob) {
      resolve(blob)
     }, type || 'image/png', quality) 
    })
}

这里通过控制 canvas的宽高, 以及对 canvastoBlob设置参数, 来实现自定义的图片压缩.

如果大家对代码有不理解的地方, 也可以在文末发表问题, 我会做出对应的解答.

更多前端提效方案

  • xijs 一款面向复杂业务场景的javascript工具库
  • react-slider-vertify 基于react实现的滑动验证码组件
  • react-cropper-pro 支持图片上传+裁切+压缩的组件
  • h5-dooring 在线H5页面制作工具
  • v6.Dooring 可视化大屏搭建平台
标签: cropper

相关文章

工作中,前端开发要看项目,怎么查看别人的js项目代码

怎么看别人的项目进入公司后,不可能一直做新项目,大多数都是从上一个同事的项目手上开始入手,或者说参与到团队中来开发项目;因此读懂一个项目并能快速的实践是重中之重。下面我将对新手入职新公司怎么了解的项目...

全新品牌!TME律所代理Weezer美国摇滚乐队起诉,涉及商标侵权!

威瑟乐团(Weezer)是一组来自美国加州洛杉矶的另类摇滚乐团,于1992年组成。乐团最初由瑞弗斯·柯摩(Rivers Cuomo,主唱、吉他手)、帕特里克·威尔森(Patrick Wilson,鼓手...

给半裙一个机会,它能给你最时髦的春天

初春的第一条半裙,你选好了吗?随着气温逐渐回暖,人们对于冬季穿搭长久以来的敬畏之心也巧妙地被一些单品所化解。而在这些单品中,必不可少的一定是这条能与温度和季节完美契合的半裙。特别是在令人头疼的换季尴尬...

摒弃迷你裙,一切以牛仔长裙为重

迷你裙在我们的时尚意识中似乎永远占据着主导地位,但设计师们最近做出了一个受欢迎的举动,即摆脱了打底裤的束缚。这一季是关于别致的、贴身的风格,是为了修饰任何人和所有人,不管你多高。每一季,设计师都会用新...

SpringBoot+Ant Design+Vue+Mybatis+Shiro快速开发平台源码分享

关注转发文章之后私信回复关键字【源码】即可免费获取到!项目简介:一款基于代码生成器的J2EE快速开发平台!采用前后端分离架构:SpringBoot2.x,Ant Design&Vue,Mybatis-...

一课译词:栽跟头

[Photo/Pixabay]在漫漫人生道路上,我们免不了要“栽跟头”。摔倒并不可怕,重要的是要学会重新站起来。“栽跟头”,本意是“摔跤,跌跤(tumble; fall)”,常用来比喻经历失败或遭受挫...

发表评论    

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