js上传图片之前利用canvas压缩和转base64

2 篇文章 0 订阅
1 篇文章 0 订阅

js上传图片之前利用canvas压缩和转base64

简介

img-compress-tool 是一个通过js和canvas api 对图片文件进行压缩,实现基于es6的语法,适用于pc端和移动端

使用方法

Install

  • 直接通过npm的方法安装,或者到github上clone到代码到本地

    npm install img-compress-tool
    
    git clone https:github.com/landluck/img-compress
    

Use

  • 引入ImgCompress 类

    import ImgCompress from 'img-compress-tool'
    
  • 创建一个实例,传入所需要的参数

    1. file 为 Image对象, 必须传入图片文件,否则会抛出错误,
    2. quality 为 压缩质量 ,最小为 0 , 最大为1,超出范围,抛出错误, 默认值为 0.5
    3. size 图片大小限制, 传入的图片大小大于size的时候,对图片进行压缩,小于size,直接返回原文件, 默认值我1024kb
    4. width 将要生成的图片宽度,默认原大小,图片保持纵横比
    5. callbackHandle 图片压缩完成后的回调函数,因为图片压缩使用了img.onload 异步加载,所以图片压缩是异步的,利用回调函数保证图片压缩完成

      const img = new ImgCompress(file, quality, size, width).initCompress(callbackHandle)
      
  • 回调函数中会返回一个实例对象data,属性有

    1. file 压缩之后的图片文件,可用于直接上传
    2. baseUrl 压缩之后的base64,可用于预览图片
    3. oldFile 原有文件,未经压缩
    4. oldBaseUrl 原有base64

       function callbackHandle (data) {
         let file = data.file
         let baseUrl = data.baseUrl
       }
      

具体实现

// exprot default 实例对象
export default class ImageCompress {
    // 传入参数
  constructor(file, quality = 0.5, size = 1024, w) {
    this.oldFile = file
    this.quality = quality
    this.size = size
    // 判断是否传入width参数
    if (w) this.w = w
    this.checkFormat()
  }
  // 检查传入参数的格式正确与否
  checkFormat() {
    // 检查传入的图片格式
    if (typeof this.oldFile !== 'object' || !this.oldFile.type || this.oldFile.type.split('/')[0] !== 'image') {
      throw new Error(' file type  must be Image Object ')
    }
    // 检查传入的quality 质量格式
    if (typeof this.quality !== 'number' || this.quality > 1 || this.quality < 0) {
      throw new Error(' quality must be Number and lt 1 , gt 0 ')
    }
    // 检查传入的 size 格式
    if (typeof this.size !== 'number' || this.size < 0) {
      throw new Error(' size must be Number and gt 0')
    }
  }
  // 对外的压缩函数,传入参数callback   
  initCompress(callback) {
    // 检查传入的callback的格式
    if (!callback || type of callback !== 'function') {
        throw new Error(' initCompress must have callback function')
    }
    let that = this
    let ready = new FileReader()
    // 读取传入的文件
    ready.readAsDataURL(this.oldFile)
    ready.onload = function () {
      // 将文件传入base64    
      that.oldBaseUrl = this.result
      // 判断文件大小 
      // 大于传入的size,对图片进行压缩,小于直接callback原有文件 
      if (that.oldFile.size / 1024 > that.size) {
        that.canvasDataURL(callback)
        return
      }
      that.baseUrl = this.result
      that.file = that.oldFile
      callback(that)
    }
  }
  // 利用canvas 对图片进行压缩   
  canvasDataURL(callback) {
    let that = this
    let img = new Image()
    img.src = this.oldBaseUrl
    img.onload = function () {
      // 默认按比例压缩
      let w = this.width
      let h = this.height
      let scale = w / h
      if (that.w) {
        w = that.w
        h = w / scale
      }
      let quality = that.quality
      // 生成canvas
      let canvas = document.createElement('canvas')
      let ctx = canvas.getContext('2d')
      // 创建属性节点
      let anw = document.createAttribute('width')
      anw.nodeValue = w
      let anh = document.createAttribute('height')
      anh.nodeValue = h
      canvas.setAttributeNode(anw)
      canvas.setAttributeNode(anh)
      ctx.drawImage(this, 0, 0, w, h)
      // The smaller the quality value, the more blurred the image is drawn
      let base64 = canvas.toDataURL('image/jpeg', quality)
      // 将图片从base64 转回文件格式  
      let arr = base64.split(',')
      let mime = arr[0].match(/:(.*?)/)[1]
      let bstr = atob(arr[1])
      let n = bstr.length
      let u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      that.file = new Blob([u8arr], {
        type: mime
      })
      // 成功回调
      callback(that)
    }
  }
}

小结

最近工作中的vue项目用到了图片压缩上传,没找到好的插件,索性自己琢磨了一个简单的压缩工具,目前限制很大,功能很小,将会持续更新,争取做到一个比较完善的插件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值