Canvas实现图片压缩上传

接到产品需求,问能不能将前端上传的图片压缩?像移动端上传图片,一般都是超清、高清图片,大小也有10M,甚至一张图片大小有15M左右,这样大的图片上传到腾讯云或者阿里云(没使用服务器上传图片)一方面上传速度慢,影响体验,另一方面体积太大占空间,图片压缩避免了,网上搜到了很多这方面介绍的网址,大多数都是用canvas来实现(不说了,马上开干)!。

实现过程 (10M 压缩至 200k左右)

1. 图片裁剪

大体的思路是将图片抽样显示在canvas上,然后用通过canvas.toDataURL方法得到base64字符串来实现压缩。上代码!!!

    const file: {} = e.target.files[0]; // 通过input元素触发的change事件
    const reader = new FileReader(),
    img = new Image();
    // 缩放图片需要的canvas
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    reader.readAsDataURL(file);
    // base64地址图片加载完毕后
    img.onload = function () {
      // 图片原始尺寸
      const originWidth = this['width'];
      const originHeight = this['height'];
      // 最大尺寸限制
      const maxWidth = 750, maxHeight = 400;
      // 目标尺寸
      let targetWidth = originWidth, targetHeight = originHeight;
      // 图片尺寸超过750x400的限制
      if (originWidth > maxWidth || originHeight > maxHeight) {
        if (originWidth / originHeight > maxWidth / maxHeight) {
          // 更宽,按照宽度限定尺寸
          targetWidth = maxWidth;
          targetHeight = Math.round(maxWidth * (originHeight / originWidth));
        } else {
          targetHeight = maxHeight;
          targetWidth = Math.round(maxHeight * (originWidth / originHeight));
        }
      }

      // canvas对图片进行缩放
      canvas.width = targetWidth;
      canvas.height = targetHeight;
      // 清除画布
      context.clearRect(0, 0, targetWidth, targetHeight);
      // 图片压缩
      context.drawImage(img, 0, 0, targetWidth, targetHeight);
      // canvas转为blob并上传
      // * 很多PC、手机浏览器不支持toBlob方法,如Safari*
      // 不推荐使用toBlob方法
      // canvas.toBlob(function($Blob) {
      // })
      const dataUrl = canvas.toDataURL('image/jpeg');
      updateImgForBase64(dataUrl);
    }
    reader.onload = function (e) {
        img.src = e.target['result'];
    };

2. 上传到腾讯云

项目中图片是保存在腾讯云中,这里就需要用到腾讯JavaScript SDK,按照SDK文档去新建存储桶获取Bucket、Region,直接上代码:

updateImgForBase64(img: string, type: string = 'jpeg'): Promise<any> {
    const vm = this;
    const storeAs = `avatar/${new Date().getTime()}-${this.guid()}.${type}`;
    const dataURLtoFile: Function = (dataurl, filename) => {
      const arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1];
      const bstr = atob(arr[1]);
      let n = bstr.length;
      const u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], filename, {type: mime});
    };
    const file = dataURLtoFile(img, type);
    
    // function getBlobBydataURI(dataURI, type) {
    //   var binary = atob(dataURI.split(',')[1]);
    //   var array = [];
    //   for (var i = 0; i < binary.length; i++) {
    //     array.push(binary.charCodeAt(i));
    //   }
    //   return new Blob([new Uint8Array(array)], {type: type});
    // }
    //
    // /**
    //  * 上传  formData.append("files", $Blob, storeAs);对iOS系统不支持
    //  */
    //   //base64 转 blob
    // let $Blob = getBlobBydataURI(img, 'image/jpeg');
    // let formData = new FormData();
    // let storeAs = `documents/${new Date().getTime()}-${this.guid()}.${type}`;
    // formData.append("files", $Blob, storeAs);
    //组建XMLHttpRequest 上传文件
    return new Promise((resolve, reject) => {
      this.cos.sliceUploadFile({
        Bucket: 'your bucket',
        Region: 'your region',
        Key: storeAs,
        Body: file
      }, function (err, data) {
        if (err) {
          reject(JSON.stringify(err));
        } else {
          resolve(url);
        }
      });
    })
  }

喜欢我的关注下方公众号: 生活充电堡。繁忙的生活也要时刻保持充电
Canvas实现图片压缩上传_第1张图片Canvas实现图片压缩上传_第2张图片
Canvas实现图片压缩上传_第3张图片

你可能感兴趣的:(图片压缩,图片裁剪,腾讯云,JS)