RicoLiu/Blog

<el-upload> 实现图片压缩上传

Opened this issue · 0 comments

el-upload 组件不支持图片压缩上传,只能自己实现了。

图片压缩核心就是:canvas

compress.js

/** 图片压缩
 * @param {Number} orient iphone & android 拍照图片方向
 * @param {Object} fileObj 图片对象
 * @param {function} cb 回调函数
 */
export function compress (orient, fileObj, cb) {
  try {
    // 压缩图片需要的一些元素和对象
    let img = new Image();

    // 缩放图片需要的canvas
    let canvas = document.createElement('canvas');
    let context = canvas.getContext('2d');
    img.src = URL.createObjectURL(fileObj);
    // base64地址图片加载完毕后
    img.onload = function () {
      // 图片原始尺寸
      let originWidth = this.width;
      let originHeight = this.height;

      if (originWidth > originHeight && originWidth > 750) {
        originWidth = 750;
        originHeight = Math.ceil(750 * this.height / this.width);
      } else if (originWidth < originHeight && originHeight > 1334) {
        originWidth = Math.ceil(1334 * this.width / this.height);
        originHeight = 1334;
      }
      let targetWidth = originWidth;
      let targetHeight = originHeight;
      // canvas对图片进行缩放
      canvas.width = targetWidth;
      canvas.height = targetHeight;
      // 清除画布
      context.clearRect(0, 0, targetWidth, targetHeight);
      if (orient && orient !== 1) {
        switch (orient) {
          case 6:
            canvas.width = targetHeight;
            canvas.height = targetWidth;
            context.rotate(Math.PI / 2);
            context.drawImage(img, 0, -targetHeight, targetWidth, targetHeight);
            break;
          case 3:
            context.rotate(Math.PI);
            context.drawImage(img, -targetWidth, -targetHeight, targetWidth, targetHeight);
            break;
          case 8:
            canvas.width = targetHeight;
            canvas.height = targetWidth;
            context.rotate(3 * Math.PI / 2);
            context.drawImage(img, -targetWidth, 0, targetWidth, targetHeight);
            break;
          default:
            context.drawImage(img, 0, 0, targetWidth, targetHeight);
            break;
        }
      } else {
        context.drawImage(img, 0, 0, targetWidth, targetHeight);
      }
      // 图片压缩
      // context.drawImage(img, 0, 0, targetWidth, targetHeight);
      // canvas转为blob并上传
      canvas.toBlob(function (blob) {
        cb(blob);
        console.log('压缩成功 toblob ', URL.createObjectURL(blob));
      }, fileObj.type || 'image/png');
    };
  } catch (e) {
    console.log('压缩失败:', e)
  }
}

upload.vue

import { compress } from './compress.js'

handlePictureCardPreview(file) {
        compress(file.raw, function(val) {
          console.log('success.....', URL.createObjectURL(val))
          let formdata = new FormData();
          formdata.append('file', val);
          // 图片ajax上传
          let xhr = new XMLHttpRequest();
          // 文件上传成功
          xhr.onreadystatechange = function() {
            if (xhr.status == 200) {
              // xhr.responseText就是返回的数据
              console.log('response data: ', xhr.responseText)
            }
          };
          // 开始上传
          xhr.open("POST", "xxxxxx", true);
          xhr.send(formdata);
       })
},
beforeAvatarUpload(file) {
        const isJPG = file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/jpg' || file.type === 'image/jpeg';
        const isLt10M = file.size / 1024 / 1024 < 10;
        if (!isJPG) {
          this.$message.error('上传头像图片只能是 JPG,gif,png,jpeg 格式!');
        }
        if (!isLt10M) {
          this.$message.error('上传头像图片大小不能超过 10MB!');
        }
        return false;
},