Bootstrap

JS将base64图片压缩至指定大小

base64图片压缩至指定大小

  1. 在开发中,通常在上传图片时,由于各种限制,需要将上传的图片压缩到某一大小范围内才能上传。在此提供以下方法实现该需求,复制可用。

压缩图片原理

  1. 通过原生的input标签拿到要上传的图片文件
  2. 将图片文件file对象转化成图片base64
  3. 根据图片base64创建img图片对象
  4. 在canvas上绘制该HTMLImageElement
  5. 通过不断降低图片质量指数来达到压缩图片大小的目的

封装

  1. 将以上代码封装为一个js文件,这里命名为compressImg.js,放置在utils文件夹下

    /**
     * 压缩图片到指定大小
     * @param baseImg base64图片
     * @param maxSize 单位kb
     */
    export function compressImgBySize (baseImg, maxSize = 200) {
      return new Promise((resolve) => {
      	// 计算图片大小
        const strLength = baseImg.length
        const fileLength = parseInt(strLength - (strLength / 8) * 2)
        let size = parseInt((fileLength / 1024).toFixed(2))
    
    	// 判断图片是否符合指定大小要求
        if (size <= maxSize) {
          resolve(baseImg)
          return
        }
    
    	// 创建image对象
        const img = new Image()
        if (baseImg.indexOf('data:image/') !== -1) {
          img.src = baseImg
       	} else {
          img.src = 'data:image/jpeg;base64,' + baseImg
    	}
    	
        img.onload = () => {
          // 把image对象 转换为 canvas对象
          const canvas = imgToCanvas(img)
          let resUrl = ''
          // 图片质量,范围:0 ~ 1
          let quality = 0.9
          
          // 当图片大小大于指定maxSize,图片质量大于0时继续通过降低图片资料来压缩
          while (size > maxSize && quality > 0) {
          	// 在canvas上绘制该HTMLImageElement,得到图片base64
            resUrl = canvas.toDataURL('image/jpeg', quality).replace(/^data:image\/\w+;base64,/, '')
            const resLength = resUrl.length
            // 计算绘制出的base64图片大小
            const resFileLength = parseInt(resLength - (resLength / 8) * 2)
            size = parseInt((resFileLength / 1024).toFixed(2))
            // 降低图片质量
            quality = (quality - 0.1).toFixed(1)
          }
          resolve(resUrl)
        }
        img.onerror = () => {
          resolve(baseImg)
        }
      })
    }
    
    // 把image 转换为 canvas对象
    export function imgToCanvas (image) {
      var canvas = document.createElement('canvas')
      canvas.width = image.width
      canvas.height = image.height
      canvas.getContext('2d').drawImage(image, 0, 0)
      return canvas
    }
    
  2. 在需要使用图片压缩的.vue文件中引入并使用,如下

    // 注意引入路径是否正确
    import { compressImgBySize } from '@/utils/compressImg'
    
    // this.applyFile[0].content 为指定的base64格式照片
    // 1200 指将图片压缩到1200kb大小以下
    compressImgBySize('file文件对象', 1200).then(baseImg => {
    	// 输出图片base64
    	console.log(baseImg)
    })
    
;