react 图片压缩

common.js

export const common = {
  // 这里的获取exif要将图片转ArrayBuffer对象,这里假设获取了图片的baes64
  // 步骤一
  // base64转ArrayBuffer对象
  base64ToArrayBuffer: (base64) => {
    base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '')
    var binary = atob(base64) //atob() 方法用于解码使用 base-64 编码的字符串,windows对象里的方法
    var len = binary.length
    var buffer = new ArrayBuffer(len)  // 创建一个binary.length字节的ArrayBuffer
    var view = new Uint8Array(buffer)//创建一个buffer的引用,类型是Uint8,起始位置在0,结束位置为缓冲区尾部
    for (var i = 0; i < len; i++) {
      view[i] = binary.charCodeAt(i) //在引用指定位置里存入指定位置的字符的 Unicode 编码
    }
    return buffer //最终生成一个数组缓冲区,里面存储了该base64图片的二进制信息 ,为了后续通过底层接口拿到多种数值类型
  },
  // 步骤二,Unicode码转字符串
  // ArrayBuffer对象 Unicode码转字符串
  getStringFromCharCode: (dataView, start, length) => {
    var str = ''
    var i
    for (i = start, length += start; i < length; i++) {
      str += String.fromCharCode(dataView.getUint8(i))
    }
    return str //将第一步中的二进制ArrayBuffer对象生成的unicode的码转成字符串
  },

  // 步骤三,获取jpg图片的exif的角度(在ios体现最明显)下面很多都是为了获取图片数值的底层信息,陌生的大家可以一个个查,或者去看extjs官网
  getOrientation: (arrayBuffer) => {
    var dataView = new DataView(arrayBuffer) //可以从 二进制[`ArrayBuffer`]对象中读写多种数值类型的底层接口
    var length = dataView.byteLength
    var orientation
    var exifIDCode
    var tiffOffset
    var firstIFDOffset
    var littleEndian
    var endianness
    var app1Start
    var ifdStart
    var offset
    var i
    // Only handle JPEG image (start by 0xFFD8)
    if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
      offset = 2
      while (offset < length) {
        if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
          app1Start = offset
          break
        }
        offset++
      }
    }
    if (app1Start) {
      exifIDCode = app1Start + 4
      tiffOffset = app1Start + 10
      if (common.getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
        endianness = dataView.getUint16(tiffOffset)
        littleEndian = endianness === 0x4949

        if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
          if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
            firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian)

            if (firstIFDOffset >= 0x00000008) {
              ifdStart = tiffOffset + firstIFDOffset
            }
          }
        }
      }
    }

    if (ifdStart) {
      length = dataView.getUint16(ifdStart, littleEndian)
      var standalone = window.navigator.standalone,
        userAgent = window.navigator.userAgent.toLowerCase(),
        safari = /safari/.test(userAgent),
        ios = /iphone|ipod|ipad/.test(userAgent)

      for (i = 0; i < length; i++) {
        offset = ifdStart + i * 12 + 2
        if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {

          // 8 is the offset of the current tag's value
          offset += 8

          // Get the original orientation value
          orientation = dataView.getUint16(offset, littleEndian)

          // Override the orientation with its default value for Safari (#120)
          // if (IS_SAFARI_OR_UIWEBVIEW) {
          //  dataView.setUint16(offset, 1, littleEndian);
          // }
          if (ios) {
            if (!standalone && safari) {
              dataView.setUint16(offset, 1, littleEndian)
            } else if (standalone && !safari) {
              //standalone
            } else if (!standalone && !safari) {
              dataView.setUint16(offset, 1, littleEndian)
            };
          }
          break
        }
      }
    }
    return orientation
  }
}

图片转为base64

urlTobase64 (url) {
    uni.request({
      url: url,
      method: 'GET',
      responseType: 'arraybuffer',
      success: (res) => {
        let base64 = uni.arrayBufferToBase64(res.data) //把arraybuffer转成base64
        base64 = 'data:image/jpeg;base64,' + base64 //不加上这串字符,在页面无法显示
        const or = common.getOrientation(common.base64ToArrayBuffer(base64))
        ImageCompress(base64, or)
      }
    })
}

压缩图片

function ImageCompress (file, Orientation) {
  var file,
    image = new Image()
    if (file) {
      image.src = file
      image.onload = function () {
        var imgWidth = this.width,
          imgHeight = this.height,
          maxWidth = 1280
        // 控制上传图片的宽高 
        if (imgWidth > imgHeight && imgHeight > maxWidth) {
          imgWidth = maxWidth
          imgHeight = Math.ceil(maxWidth * this.height / this.width)
        } else if (imgWidth < imgHeight && imgWidth > maxWidth) {
          imgWidth = Math.ceil(maxWidth * this.width / this.height)
          imgHeight = maxWidth
        }
        var canvas = document.createElement("canvas"),
          ctx = canvas.getContext('2d')
        canvas.width = imgWidth
        canvas.height = imgHeight
        if (Orientation && Orientation != 1) {
          switch (Orientation) {
            case 6:     // 旋转90度 
              canvas.width = imgHeight
              canvas.height = imgWidth
              ctx.rotate(Math.PI / 2)
              // (0,-imgHeight) 从旋转原理图那里获得的起始点 
              ctx.drawImage(this, 0, -imgHeight, imgWidth, imgHeight)
              break
            case 3:     // 旋转180度 
              ctx.rotate(Math.PI)
              ctx.drawImage(this, -imgWidth, -imgHeight, imgWidth, imgHeight)
              break
            case 8:     // 旋转-90度 
              canvas.width = imgHeight
              canvas.height = imgWidth
              ctx.rotate(3 * Math.PI / 2)
              ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight)
              break
          }
        } else {
          ctx.drawImage(this, 0, 0, imgWidth, imgHeight)
        }
        var ndata = canvas.toDataURL("image/jpeg", 0.98)    // 压缩质量为0.98  压缩图片路径
       
      }

    }

}

你可能感兴趣的:(react.js,前端,前端框架)