angular实现图片压缩、裁剪功能

<nz-descriptions-item nzTitle="头像" nzSpan="24">
            <nz-upload class="avatar-uploader" nzAction="/baseupload" nzListType="picture-card"
              [nzShowUploadList]="false" [nzBeforeUpload]="beforeUpload" [nzCustomRequest]="customReq"
              (nzChange)="handleChange($event)">
              <ng-container *ngIf="!vConfig.userInfo.portrait">
                <i class="upload-icon" nz-icon [nzType]="vConfig.imgLoading ? 'loading' : 'plus'"></i>
                <div class="ant-upload-text">上传</div>
              </ng-container>
              <img *ngIf="vConfig.userInfo.portraitUrl" [src]="vConfig.userInfo.portraitUrl" class="avatar" />
            </nz-upload>
</nz-descriptions-item>

 ng组件地址:上传 Upload - NG-ZORRO (ant.design)

 

//上传文件之前的钩子
  beforeUpload = (file: File) => {
    return new Observable((observer: Observer<boolean>) => {
      const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/gif';
      if (!isJPG) {
        this.msgSrv.error('文件上传格式的错误,只能传JPG、JPEG、PNG、GIF格式!');
        observer.complete();
        return;
      }
      const isLt2M = file.size / 1024 / 1024 < 5;
      if (!isLt2M) {
        this.msgSrv.error('文件需小于5M');
        observer.complete();
        return;
      }
      observer.next(isJPG && isLt2M);
      observer.complete();
    });
  };
  //转换上传的文件
  customReq = (item: UploadXHRArgs) => {
    const filereader = new FileReader();
    filereader.readAsDataURL(item.file as any);
    filereader.onload = () => {
      const result: any = filereader.result; // 转换后的文件数据存储在filereader对象的result中
      const image = new Image();// 新建一个img标签 做canvas操作
      image.src = result;//加载base64格式的原图
      image.onload = () => {
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d'); // context相当于画笔,里面有各种可以进行绘图的API
        let imageWidth = 0;
        let imageHeigth = 0;
        if (image.width > image.height) {//例如:180*190,截取为180*180
          imageWidth = image.height;
          imageHeigth = image.height;
        } else {
          imageWidth = image.width;
          imageHeigth = image.width;
        }
        let imgData = ''; // 存储压缩后的图片
        canvas.width = imageWidth; // 设置绘图的宽度
        canvas.height = imageHeigth; // 设置绘图的高度
        // 使用drawImage重新设置img标签中的图片大小,实现压缩和图片裁剪
        context.clearRect(0, 0, canvas.width, canvas.height);
        // context.drawImage(image, 0, 0, canvas.width, canvas.height);
        context.drawImage(image, 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height);
        imgData = canvas.toDataURL('image/png');//将canvas上的图片转换为base64格式
        if (imgData) {
          let files = this.base64ToFile(imgData);//将base64 的图片转换成file对象上传
          const formData = new FormData();
          formData.append('avatar', files);
          this.http.post("/baseupload", formData).subscribe(res => {
            if (res.code === 200) {
              this.vConfig.userInfo.portrait = res.obj.name;
              this.vConfig.userInfo.portraitUrl = res.obj.url;
            }
          });
        }
      }
    }
  }

  // 将base64 的图片转换成file对象上传
  base64ToFile(data) {
    // atob将ascii码解析成binary数据
    let binary = atob(data.split(',')[1]);
    let mime = data.split(',')[0].match(/:(.*?);/)[1];
    let array = [];
    for (let i = 0; i < binary.length; i++) {
      array.push(binary.charCodeAt(i));
    }
    let fileData = new Blob([new Uint8Array(array)], {
      type: mime,
    });
    let file = new File([fileData], `${new Date().getTime()}.png`, { type: mime });
    return file;
  }

handleChange(info: { file: UploadFile }): void {
    switch (info.file.status) {
      case 'uploading':
        this.vConfig.imgLoading = true;
        break;
      case 'done':
        // Get this url from response in real world.
        // this.getBase64(info.file!.originFileObj!, (img: string) => {
        //   this.vConfig.imgLoading = false;
        //   this.vConfig.userInfo.portrait = img;
        // });
        const res = info.file.response;
        this.vConfig.imgLoading = false;
        if (res.code === 200) {
          this.vConfig.userInfo.portrait = res.obj.name;
          this.vConfig.userInfo.portraitUrl = res.obj.url;
        }
        break;
      case 'error':
        this.msgSrv.error('网络错误');
        this.vConfig.imgLoading = false;
        break;
    }
  }

 

参考:angular7中实现图片上传、图片压缩、图片裁剪功能_yw00yw的博客-CSDN博客

  

posted @ 2021-05-13 17:26  柠檬青味  阅读(552)  评论(0编辑  收藏  举报