美文网首页
vue Vant上传图片压缩图片

vue Vant上传图片压缩图片

作者: 嫑着急 | 来源:发表于2020-11-18 15:47 被阅读0次
          <template>
              <van-uploader :after-read="afterRead" v-show='is_img' />
          </template>
    
          npm install exif-js --save   安装
          import Exif from 'exif-js'
    
          data() {
             return {
                  // 图片信息
                    files: {
                         name: "",
                         type: ""
                     },
             }
          },
        
          // 上传图片
          afterRead(file) {
            this.files.name = file.file.name // 获取文件名
            this.files.type = file.file.type // 获取类型
            this.imgPreview(file.file)
          },
          // 处理图片
          imgPreview(file) {
            let self = this
            let Orientation
            //去获取拍照时的信息,解决拍出来的照片旋转问题   npm install exif-js --save   这里需要安装一下包
            Exif.getData(file, function() {
              Orientation = Exif.getTag(this, 'Orientation')
            })
            // 看支持不支持FileReader
            if (!file || !window.FileReader) return
            if (/^image/.test(file.type)) {
              // 创建一个reader
              let reader = new FileReader()
              // 将图片2将转成 base64 格式
              reader.readAsDataURL(file)
              // 读取成功后的回调
              reader.onloadend = function() {
                let result = this.result
                let img = new Image()
                img.src = result
                //判断图片是否大于500K,是就直接上传,反之压缩图片
                if (this.result.length <= 500 * 1024) {
                  // 上传图片
                  self.postImg(this.result);
                } else {
                  img.onload = function() {
                    let data = self.compress(img, Orientation)
                    // 上传图片
                    self.postImg(data);
                  }
                }
              }
            }
          },
          // 压缩图片
          compress(img, Orientation) {
            let canvas = document.createElement('canvas')
            let ctx = canvas.getContext('2d')
            //瓦片canvas
            let tCanvas = document.createElement('canvas')
            let tctx = tCanvas.getContext('2d')
            // let initSize = img.src.length;
            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) {
              // console.log("超过100W像素");
              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)
            }
            //修复ios上传图片的时候 被旋转的问题
            if (Orientation != '' && Orientation != 1) {
              switch (Orientation) {
                case 6: //需要顺时针(向左)90度旋转
                  this.rotateImg(img, 'left', canvas)
                  break
                case 8: //需要逆时针(向右)90度旋转
                  this.rotateImg(img, 'right', canvas)
                  break
                case 3: //需要180度旋转
                  this.rotateImg(img, 'right', canvas) //转两次
                  this.rotateImg(img, 'right', canvas)
                  break
              }
            }
            //进行最小压缩
            let ndata = canvas.toDataURL('image/jpeg', 0.2)
            tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
            console.log(ndata)
            return ndata
          },
          // 旋转图片
          rotateImg(img, direction, canvas) {
            //最小与最大旋转方向,图片旋转4次后回到原方向
            const min_step = 0
            const max_step = 3
            if (img == null) return
            //img的高度和宽度不能在img元素隐藏后获取,否则会出错
            let height = img.height
            let width = img.width
            let step = 2
            if (step == null) {
              step = min_step
            }
            if (direction == 'right') {
              step++
              //旋转到原位置,即超过最大值
              step > max_step && (step = min_step)
            } else {
              step--
              step < min_step && (step = max_step)
            }
            //旋转角度以弧度值为参数
            let degree = (step * 90 * Math.PI) / 180
            let ctx = canvas.getContext('2d')
            switch (step) {
              case 0:
                canvas.width = width
                canvas.height = height
                ctx.drawImage(img, 0, 0)
                break
              case 1:
                canvas.width = height
                canvas.height = width
                ctx.rotate(degree)
                ctx.drawImage(img, 0, -height)
                break
              case 2:
                canvas.width = width
                canvas.height = height
                ctx.rotate(degree)
                ctx.drawImage(img, -width, -height)
                break
              case 3:
                canvas.width = height
                canvas.height = width
                ctx.rotate(degree)
                ctx.drawImage(img, -width, 0)
                break
            }
          },
          //将base64转换为文件
          dataURLtoFile(dataurl) {
            var arr = dataurl.split(','),
              bstr = atob(arr[1]),
              n = bstr.length,
              u8arr = new Uint8Array(n)
            while (n--) {
              u8arr[n] = bstr.charCodeAt(n)
            }
            return new File([u8arr], this.files.name, {
              type: this.files.type
            })
          },
          // 提交图片到后端
          postImg(base64) {
            let file = this.dataURLtoFile(base64)
            let formData = new window.FormData()
            formData.append('file', file)
            // 提交图片
            let config = {
              headers: {
                "Content-Type": "multipart/form-data"
              }
            };
            this.$axios.post("https://mail.xxxxxxx.com/shop/file/uploadimg", formData, config)
              .then((res) => {
                // console.log(res.data.msg);
                this.img = res.data.msg
                this.fs()
              })
            // Some code
          },
    

    相关文章

      网友评论

          本文标题:vue Vant上传图片压缩图片

          本文链接:https://www.haomeiwen.com/subject/vpuciktx.html