跳至主要內容

压缩图片

Mr.Chen开发日志项目总结大约 3 分钟约 795 字

//压缩图片
onChange = (files, type, index) => {
  if (type === 'add') {
    let imageList = []
    files.map((item, index) => {
      return lrz(item.url, {
        quality: 0.7
      }).then(rst => {
        // 处理成功会执行
        imageList.push(rst.base64)
        this.setState({ imagesrc: imageList })
      })
    })
  } else {
    this.setState({ imagesrc: [] })
  }

  this.setState({ files })
}
;(function () {
  var coverImage = document.querySelector('<div id="coverImage">file</div>')
  //图片压缩
  coverImage.onchange = function () {
    lrz(this.files[0], { width: 640 }, function (results) {
      // 你需要的数据都在这里,可以以字符串的形式传送base64给服务端转存为图片。
      var base64 = results.base64
      function base64UrlToBlob(base64) {
        var bytes = window.atob(base64.split(',')[1]) //去掉url的头,并转换为byte
        //处理异常,将ascii码小于0的转换为大于0
        var ab = new ArrayBuffer(bytes.length)
        var ia = new Uint8Array(ab)
        for (var i = 0; i < bytes.length; i++) {
          ia[i] = bytes.charCodeAt(i)
        }
        return new Blob([ab], { type: 'image/jpg' }) //return Blob对象
      }
      var formData = new FormData($('#toPic')[1])
      var blob = base64UrlToBlob(base64)
      console.log(blob)
      formData.append('coverImage', blob)
      $.ajax({
        url: 'xxx',
        type: 'POST',
        data: formData,
        dataType: 'json',
        contentType: false,
        processData: false,
        success: function (json) {
          console.log(json)
        }
      })
      setTimeout(function () {
        demo_report('预压的图片', base64, base64.length * 0.5)
      }, 100)
    })
  }
})()

将 blob 对象转二进制 buffer

在客户端,返回的数据是 blob 二进制数据,那么怎么将它向客户端进行解压呢?最后通过 renderer 对象成功解决:

var render = new FileReader()
render.onloadend = function () {
  var ms = pako.inflate(render.result, {
    to: 'string'
  })
  var msg = JSON.parse(ms)
  if (msg.ping) {
    that.websocket.send(
      JSON.stringify({
        pong: msg.ping
      })
    )
  } else if (msg.tick) {
    var attr = msg.ch.split('.')[1]
    document.querySelector('.' + that.name + attr).innerHTML = parseFloat(
      msg.tick.close
    )
  }
}
render.readAsBinaryString(e.data)

url 转 base64 base64 转 blob

function getBase64(img) {
  //传入图片路径,返回base64
  function getBase64Image(img, width, height) {
    //width、height调用时传入具体像素值,控制大小 ,不传则默认图像大小
    var canvas = document.createElement('canvas')
    canvas.width = width ? width : img.width
    canvas.height = height ? height : img.height

    var ctx = canvas.getContext('2d')
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
    var dataURL = canvas.toDataURL()
    return dataURL
  }
  var image = new Image()
  image.src = img
  var deferred = $.Deferred()
  if (img) {
    image.onload = function () {
      deferred.resolve(getBase64Image(image)) //将base64传给done上传处理
    }
    return deferred.promise() //问题要让onload完成后再return sessionStorage['imgTest']
  }
}
function base64toBlob(dataurl) {
  var arr = dataurl.split(','),
    mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], { type: mime })
}

BASE64 加密字符串,当编码的字节较长时,encode 出来的字符串会自动加入\r\n 进行自动换行。针对这个问题,原因是 rfc 规范规定 76 个字符换一次行。我们可以使用 replaceAll("\r\n", "")来进行替换。替换后,没问题了。代码示例如下:

oldphoto64code = base64encode.encode(b).replaceAll('\r\n', '')

vue 图片压缩

// unit.js
const unit = {
  /**
   * blob转file
   */
  blobToFile: (blob, fileName, mime) => {
    // ios heic 格式图片替换
    fileName = fileName.replace(".HEIC", ".jpg").replace(".heic", ".jpg");
    return new File([blob], fileName, {
      type: mime,
      lastModified: Date.now(),
    });
  },
};
export default unit;
/**
 * desc: 图片压缩
 */

import lrz from "lrz";
import unit from "./unit";

const compressImg = {
  getSize: size => {
    const fileSize = parseFloat(parseInt(size) / 1024 / 1024).toFixed(2);
    return fileSize;
  },
  resize: (file, options) => {
    return new Promise((resolve, reject) => {
      if (!file) {
    return reject(new Error("请先选择图片文件"));
      }
      const fileSize = compressImg.getSize(file["size"]);
      // 小于1M直接返回不做处理
      if (fileSize <= 1) {
    return resolve({ file: file });
      }
      if (!options) {
    // 大于1M小于5M
    if (fileSize > 1 && fileSize <= 5) {
      options = { quality: 0.92 }; // canvas默认值
    }
    // 大于5M小于10M
    if (fileSize > 5 && fileSize <= 10) {
      options = { quality: 0.9 }; // canvas默认值
    }
    // 大于10M
    if (fileSize > 10) {
      options = { quality: 0.85 };
    }
      }
      return lrz(file, options).then(res => {
    const fileName = res.origin.name;
    const mime = res.origin.type;
    const newSize = compressImg.getSize(res.fileLen);
    // 大于10M
    if (newSize > 10) {
      return reject(new Error("上传文件不能大于10M"));
    }
    const newFile = unit.blobToFile(res.file, fileName, mime);
    resolve({ file: newFile });
      }, reject);
    });
  },
};

export default compressImg;
上次编辑于: