基于canvas实现图片压缩

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Zckguiying/article/details/85312562
用法:
compressImg(target.files[0], 2).then(base64 => {
  console.log(base64)
  // 在这里实现压缩后的上传操作
  // ...
}).catch(err => { // 压缩异常
  Indicator.close()
  _this.$toast(err)
})

详细见代码注释


/**
 * 图片压缩
 * @param file 图片原文件【必传】
 * @param maxDefaultSize 压缩后的最大值限制,默认10M
 * @param quality 压缩后的质量,取值范围:(0, 1], 默认值:1
 * @param type 压缩后的文件后缀名, 默认值:'jpeg'
 * @returns {Promise<any>}
 */
export function compressImg (file = null, maxDefaultSize = 10, quality = 1, type = 'jpeg') {
  let imgQuality = quality > 1 ? 1 : quality <= 0 ? 0.1 : quality // imgQuality取值范围:(0, 1]
  let reader = new FileReader()
  let img = new Image()
  // 图片转base64后的大小
  let imgSize = 0
  // 选择的文件是图片
  if (file.type.indexOf('image') === 0) {
    reader.readAsDataURL(file)
  }
  // 文件base64化,以便获知图片原始尺寸
  reader.onload = function (e) {
    imgSize = e.total
    img.src = e.target.result
  }
  // 创建缩放图片所需的canvas
  let canvas = document.createElement('canvas')
  let context = canvas.getContext('2d')
  // 返回promise对象
  return new Promise((resolve, reject) => {
    // base64地址图片加载完毕后
    img.onload = (e) => {
      // 图片原始尺寸
      let originWidth = img.width
      let originHeight = img.height
      // 最大尺寸限制和最大图片占用空间限制
      let maxWidth = 500
      let maxHeight = 500
      let maxSize = 2 * 1024 * 1024 // 2M
      // 目标尺寸
      let targetWidth = originWidth
      let targetHeight = originHeight
      // 图片尺寸超过500*500最大尺寸的限制,或超过2M限制
      if (imgSize > maxSize || originWidth > maxWidth || originHeight > maxHeight) {
        // 图片原始宽高比例大于最大宽高比例,按照宽度限定尺寸
        if (originWidth / originHeight > maxWidth / maxHeight) {
          targetWidth = maxWidth
          targetHeight = Math.round(maxWidth * (originHeight / originWidth))
        } else {
          targetWidth = Math.round(maxHeight * (originWidth / originHeight))
          targetHeight = maxHeight
        }
      }

      // 使用canvas对图片进行缩放压缩操作
      canvas.width = targetWidth
      canvas.height = targetHeight
      // 清除画布
      context.clearRect(0, 0, targetWidth, targetHeight)
      // 图片压缩
      context.drawImage(img, 0, 0, targetWidth, targetHeight)
      // canvas转为base64上传
      let targetType = type ? `image/${type}` : file.type || 'image/jpeg'
      let base64 = canvas.toDataURL(targetType, imgQuality)
      let strContent = base64.split('base64,')[1].replace(/=/g, '')
      let contentLen = strContent.length
      let base64Size = parseInt(contentLen - (contentLen / 8) * 2)
      // 压缩后还大于压缩后最大值限制
      if (base64Size > maxDefaultSize * 1024 * 1024) {
        let errMsg = '图片过大,请重新选择'
        reject(errMsg)
      } else {
        resolve(base64)
      }
      // canvas转为blob上传
      // canvas.toBlob((blob) => {
      //   console.log('canvas转为blob上传---', blob)
      //   resolve(blob)
      // }, `image/${type}` || file.type || 'image/jpeg')
    }
    img.onerror = () => {
      let errMsg = '图片加载失败'
      reject(errMsg)
    }
  })
}

猜你喜欢

转载自blog.csdn.net/Zckguiying/article/details/85312562