前端如何压缩图片上传

951 阅读1分钟
大家在日常工作中肯定会遇到需要上传图片到后端的情况,但是呢,图片如果太大,而我们并不需要高清的图片的时候,就需要对图片进行压缩在上传,就会大大提高效率。

实现方法

监听input file的onchange事件,用FileReader 读取用户使用input file上传的图片

public url: string;

loadImg(file) {
    const reader = new FileReader();
    reader.onload = (e: any) => {
      this.url = e.target.result;
    };
    reader.readAsDataURL(file);
  }

把图片数据传入img对象,然后将img绘制到canvas上,再调用canvas.toDataURL对图片进行压缩,获取到压缩后的base64格式图片数据,转成二进制

// quality:默认压缩品质0.7,  wh:传入函数的图片压缩后的最大图片宽度和高度,默认是1000,单位是px
processImg(quality = 0.7, wh = 1000) {
    if (!this.url) {
      return;
    }
    const img = new Image();
    img.src = this.url;

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    let height = img.height;
    let width = img.width;
    let imgWH = 1000;

    if (wh && wh < 1000 && wh > 0) {
      imgWH = wh;
    }

    // 按比例缩小图片
    if (width > imgWH || height > imgWH) {
      const ratio = Math.floor((height / width * 10)) / 10;
      if (width > height) {
        width = imgWH;
        height = imgWH * ratio;
      } else {
        height = imgWH;
        width = height / ratio;
      }
      img.width = width;
      img.height = height;
    }

    canvas.width = width;
    canvas.height = height;

    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, width, height);
    ctx.drawImage(img, 0, 0, width, height);

    return canvas.toDataURL('image/jpeg', quality);
  }

获取到压缩后的图片二进制数据,转换成File对象传给后端


convertBase64toFile(base64) {
    const date = new Date().valueOf();
    const imageName = date + '.jpg';
    const imageBlob = this.dataURItoBlob(base64);

    const imageFile = new File([imageBlob], imageName, { type: 'image/jpg' });
    return imageFile;
  }

  dataURItoBlob(dataURI) {
    const byteString = atob(dataURI.split(',')[1]);
    const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    console.log(mimeString);
    const arrayBuffer = new ArrayBuffer(byteString.length);
    const int8Array = new Uint8Array(arrayBuffer);
    for (let i = 0; i < byteString.length; i++) {
      int8Array[i] = byteString.charCodeAt(i);
    }
    const blob = new Blob([int8Array], { type: 'image/jpg' });
    return blob;
  }
// angular httpClient
uploadFile(file){
    var formData = new FormData();
    formData.append("files", file);
    
    this.httpClient.post(FileUploadUrl, formData)
}

//上传图片
const fileForUpload = this.convertBase64toFile(this.processImg());
this.uploadFile(fileForUpload);

这样就完成了图片的压缩,上传,也可以预览。