vue,react,js 图片上传前对图片进行压缩,主要用于头像上传(利用canvas重绘图片已达到压缩效果)

实现原理:


新建一个web api中FileReader对象,去读取本地选中的图片,新建image对象去记录选中图片的基本信息(如: width,height等),新建"canvas"标签,利用Image对象记录的数据在"canvas"上重绘一个图片,然后再将图片转成base64编码,再处理成Blob类型返回即可

具体如下(以下例子使用的是 element-ui的上传组件)

在上传文件时,监听选中图片后、上传之前的事件

//	这是在vue中的template里的代码
<el-upload
    ref="upload"
    <!-- //     上传地址 --></el-upload>
    action="https://jsonplaceholder.typicode.com/posts/"
    <!-- //  是否支持多选文件 -->
    :multiple="false"
    name="fileName"
    <!-- //  数据 -->
    :data="uploadData"
    <!-- //  上传成功回调 -->
    :on-success="uploadSuccess"

    <!-- //  重点是监听下面的上传前的事件  -->
    <!-- //  上传前的回调 -->
    :before-upload="uploadHandle"
  ></el-upload>

监听上传前的回调,会有一个file形参,里面有上传文件的路径等信息

//  文件上传前处理
      uploadHandle(file){
        //  判断文件大小是否大于300kb,小于则不做处理
        if (file.size <= 327200){
          return
        }
        //  返回一个promise对象
        return new Promise(resolve => {
          //  用于读取本地文件的对象
          const reader = new FileReader()
          //  用于存储选中图片的基本信息
          const image = new Image()
          image.onload = (imageEvent) => {
            //  创建canvas标签元素
            const canvas = document.createElement('canvas')
            //  制定绘制的类型 这边指定的是2d类型
            const context = canvas.getContext('2d')
            //  imgQuality 指缩放的比例,我这边设置了0.5,最好用变量去定义,这样容易维护
            const width = image.width * this.imgQuality  // 0.5
            const height = image.height * this.imgQuality // 0.5
            canvas.width = width
            canvas.height = height
            //  清除canvas的矩形内容(将canvas上的东西清除)
            context.clearRect(0,0,width,height)
            //  在canvas中,按指定的比例去画出图片
            context.drawImage(image,0,0,width,height)
            //  将canvas画出的图片转成base64
            const dataUrl = canvas.toDataURL(file.type)
            //  把base64 dataUrl格式转换成blob类型(dataUrlToBlob方法在下面)
            const blobData = this.dataUrlToBlob(dataUrl,file.type)
            //  返回blobData进行上传
            resolve(blobData)
          }
          //  读取完文件后,将图片的路径存到新建的image上
          reader.onload = (e => {image.src = e.target.result})
          //  根据路径读取选中的文件
          reader.readAsDataURL(file)
        })
      },
      
      //  把base64 dataUrl格式转换为blob类型
      dataUrlToBlob(dataUrl,type){
        //  使用window的atob方法去解码base64
        let binary = atob(dataUrl.split(',')[1])
        let arr = []
        //  转unicode编码
        for (let i = 0; i < binary.length; i++) {
          arr.push(binary.charCodeAt(i))
        }
        //  通过unicode编码去创建Blob类型
        return new Blob([new Uint8Array(arr)],{type})
      }
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值