1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/**
     * 上传文件
     */
    uploadImg (file, blob, base64) {
      // 接收到回调函数 获取到压缩后图片文件 上传
      const formData = new FormData()
      // 需要给文件名添加后缀扩展名,否则传到后端的是一个没有扩展名的文件
      formData.append('file', blob, '.jpg')
       formData.append('filename', file.name)
      
      // 封装的api接口,上传提交
      api.uploadImg(formData)
        .then(res => {
          console.log(res)
        })
    },
    /**
     * 获取到的二进制文件 转 base64文件
     * @param blob
     */
    blobToBase64 (file, blob) {
      const self = this // 绑定this
      const reader = new FileReader() // 实例化一个reader文件
      reader.readAsDataURL(blob) // 添加二进制文件
      reader.onload = function (event) {
        const base64 = event.target.result // 获取到它的base64文件
        const scale = 0.92 // 设置缩放比例(0-1)
        self.compressImg(file, base64, scale, self.uploadImg) // 调用压缩方法
      }
    },
    /**
     * 压缩图片方法
     * @param base64  ----baser64文件
     * @param scale ----压缩比例 画面质量0-9,数字越小文件越小画质越差
     * @param callback ---回调函数
     */
    compressImg (file, base64, scale, callback) {
      // 处理缩放,转换格式
      // new 一个图片,用canvas来压缩
      const img = new Image()
      img.src = base64
      img.onload = function () {
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')
        
        // 默认将长宽设置为图片的原始长宽,这样在长宽不超过最大长度时就不需要再处理
        const ratio = this.width / this.height
        const maxLength = 920
        // 在长宽超过最大长度时,按图片长宽比例等比缩小
        if (this.width > maxLength || this.height > maxLength) {
          if (this.width > this.height) {
            this.width = maxLength
            this.height = maxLength / ratio
          } else {
            this.width = maxLength * ratio
            this.height = maxLength
          }
        }
        
        canvas.setAttribute('width', this.width)
        canvas.setAttribute('height', this.height)
        ctx.clearRect(0, 0, canvas.width, canvas.height)
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
        // 转成base64 文件
        const imgType = base64.split(';')[0].split(':')[1]
        base64 = canvas.toDataURL(imgType)
        // 去掉前缀data:image/jpeg;base64
        base64 = base64.substr(base64.lastIndexOf(',') + 1, base64.length)
        while (base64.length > (1024 * 100)) {
          scale -= 0.01
          base64 = canvas.toDataURL(imgType, scale)
        }
        // baser64 TO blob 
        const arr = base64.split(',')
        const mime = arr[0].match(/:(.*?);/)[1]
        const bytes = atob(arr[1])
        const bytesLength = bytes.length
        const u8arr = new Uint8Array(bytesLength)
        for (let i = 0; i < bytes.length; i++) {
          u8arr[i] = bytes.charCodeAt(i)
        }
        const blob = new Blob([u8arr], { type: mime })
        // 回调函数 根据需求返回二进制数据或者base64数据
        callback(file, blob, base64)
      }
    },