vue移动端van-uploader上传图片压缩工具类

1、最近移动端项目中使用van-uploader上传图片,开发测试都正常,上线后苹果用户反馈图片上传不了,最后排查是图片过大导致调用上传接口后一直没有返回。

2、utils文件夹下新建imgCompressUtil.js文件:

3、工具类中的具体代码:

const imgCompressUtil = {
  compressImg (file) {
    let self = this
    if (!file || !window.FileReader) return // 判断是否支持FileReader
    if (/^image/.test(file.type)) {
      let reader = new FileReader()
      reader.readAsDataURL(file) // 转成 base64 格式
      return new Promise((resolve, reject) => { // 读取成功后的回调
        reader.onloadend = function () {
          let img = new Image()
          img.src = this.result
          // 判断图片是否大于500K,是就直接上传,反之压缩图片
          if (this.result.length <= 500 * 1024) {
            resolve(this.result)
          } else {
            img.onload = function () {
              let canvas = document.createElement('canvas')
              let ctx = canvas.getContext('2d')
              let tCanvas = document.createElement('canvas')
              let tctx = tCanvas.getContext('2d')
              let width = img.width
              let height = img.height
              // 如果图片大于四百万像素,计算压缩比并将大小压至400万以下
              let ratio
              if ((ratio = (width * height) / 4000000) > 1) {
                console.log('大于400万像素')
                ratio = Math.sqrt(ratio)
                width /= ratio
                height /= ratio
              } else {
                ratio = 1
              }
              canvas.width = width
              canvas.height = height
              ctx.fillStyle = '#fff' // 铺底色
              ctx.fillRect(0, 0, canvas.width, canvas.height)
              // 如果图片像素大于100万则使用瓦片绘制
              let count
              if ((count = (width * height) / 1000000) > 1) {
                count = ~~(Math.sqrt(count) + 1) // 计算要分成多少块瓦片
                // 计算每块瓦片的宽和高
                let nw = ~~(width / count)
                let nh = ~~(height / count)
                tCanvas.width = nw
                tCanvas.height = nh
                for (let i = 0; i < count; i++) {
                  for (let j = 0; j < count; j++) {
                    tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh)
                    ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh)
                  }
                }
              } else {
                ctx.drawImage(img, 0, 0, width, height)
              }
              // 进行压缩(---------quailty越低 图片越小)
              let quailty = 0.5
              let newBase64 = canvas.toDataURL('image/jpeg', quailty)
              tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0
              resolve(newBase64) // 返回压缩后的base64
            }
          }
        }
      })
    }
  }
}

export default imgCompressUtil

4、van-uploader上传图片的内容如下,直接上传的话用content(base64),压缩的话压缩其中的file文件即可:

 5、文件压缩:

async submit() {
  Toast.loading({
    duration: 0,
    forbidClick: true,
    message: "任务反馈中..."
  })
  let files = []
  for (let i = 0; i < this.fileList.length; i++) {
    await imgCompressUtil.compressImg(this.fileList[i].file).then(res => {
      files.push(res)
    })
  }
  let params = {
    id: this.item.id,
    content: this.contentValue,
    files: files,
    meritId: this.item.meritsId,
    userId: this.userid
  }
  commonApi.feedback(params).then(res => {
    Toast.clear()
    if (res.code === '0') {
      Toast.success('任务反馈成功')
      this.$router.go(-1)
    } else {
      this.$message({ message: res.msg, type: 'warning', duration: 2000 })
    }
  })
}

上面代码中fileList中便是上传的图片集合,压缩时要用async、await,压缩后再上传便正常了。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue Vant-UI是Vue.js的一个移动端UI组件库,是一个轻量级的、高效的组件库,非常适合用于移动端前端开发。其中,Van-UploaderVant-UI的上传文件组件,允许用户将文件上传到服务器或第三方存储库。 在实现头像图片上传时,我们可以采用如下步骤: 1. 首先需要安装Vant-UI组件库。可以通过npm命令进行安装,输入如下代码:npm install vant --save 2. 在Vue项目中引入Vant-UI组件库。在main.js文件中写入如下代码:import Vant from 'vant' import 'vant/lib/vant-css/index.css' Vue.use(Vant) 3. 在需要使用上传头像的组件中引入Van-Uploader组件,并编写如下代码: <template> <van-uploader :show-upload="false" :before-read="beforeRead" :after-read="afterRead" > <van-icon name="photograph" /> </van-uploader> </template> <script> export default { data() { return { file: '' } }, methods: { beforeRead(file) { if (file.type !== 'image/jpeg' && file.type !== 'image/png') { this.$toast('请上传 JPG/PNG 格式的图片'); return false; } if (file.size > 500 * 1024) { this.$toast('图片大小不能超过 500KB'); return false; } }, afterRead(file) { this.file = URL.createObjectURL(file.file); } } } </script> 4. 上面的代码中,我们主要使用了Van-Uploader组件的before-read和after-read两个事件回调函数。before-read为上传文件之前的校验函数,例如判断文件类型和文件大小是否符合要求,这里我们限制了文件类型为JPG/PNG并且大小不能超过500KB。after-read则表示读取文件后的回调函数,我们将上传的文件读取为本地链接并保存到file属性中,以便进行后续处理。 5. 最后,将file属性传递给后端进行处理,例如将该链接保存到服务器或者上传到第三方存储库中。 总之,使用Van-Uploader组件可以轻松实现头像图片上传功能,同时也可以根据需求进行个性化的定制和扩展,是一个非常实用且易于使用的组件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值