2

我正在使用ngx-image-cropper库在我的 Angular 8 项目中裁剪图像。

我想做的是:

  • 我想在选择文件的模式内显示裁剪器。
  • 模态框有一个裁剪按钮,单击该按钮将裁剪图像(无自动裁剪)和一个取消按钮,可用于关闭模态框而不裁剪图像。
  • 裁剪图像后,模态将关闭,并且将有一个编辑按钮,可用于重新裁剪图像(单击裁剪时,我实际上是裁剪图像并隐藏模态。所以单击编辑时,我只显示再次隐藏模态。)。
  • 如果从文件输入中选择了另一个文件,则模态将与新图像一起显示。用户可以裁剪或取消。如果它被取消,我想将裁剪器的源图像重置为上一个图像。我怎样才能做到这一点?

我尝试了以下方法,但不起作用:


    lastCropperPosition: CropperPosition;
    lastCroppedImage: any;

    crop() {
        this.imageCropper.crop();
        this.lastCropperPosition = this.getCurrentCropperPosition();
        this.lastCroppedImage = new ElementRef(
          this.imageCropper.sourceImage.nativeElement
        );
        this.logoModal.hide();
    }

    cancelCrop() {
        if (this.lastCroppedImage) {
          this.imageCropper.sourceImage = this.lastCroppedImage;
        }

        if (this.lastCropperPosition) {
          this.imageCropper.cropper = this.getLastCropperPosition();
        }

        this.logoModal.hide();
    }

    getCurrentCropperPosition() {
        return {
          x1: this.imageCropper.cropper.x1,
          x2: this.imageCropper.cropper.x2,
          y1: this.imageCropper.cropper.y1,
          y2: this.imageCropper.cropper.y2
        };
    }

    getLastCropperPosition() {
        return {
          x1: this.lastCropperPosition.x1,
          x2: this.lastCropperPosition.x2,
          y1: this.lastCropperPosition.y1,
          y2: this.lastCropperPosition.y2
        };
    }

HTML 代码:

    <div bsModal #logoModal="bs-modal" class="modal fade" tabindex="-1"
      role="dialog" aria-labelledby="logoModalLabel" aria-hidden="true">
      <div class="modal-dialog" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h4 class="modal-title">Crop Image</h4>
          </div>
          <div class="modal-body">
            <image-cropper
              [imageChangedEvent]="imageChangedEvent"
              [maintainAspectRatio]="true"
              [aspectRatio]="rules.logo.maxWidth / rules.logo.maxHeight"
              [cropperMinWidth]="rules.logo.minWidth"
              [resizeToWidth]="rules.logo.maxWidth"
              [autoCrop]="false"
              onlyScaleDown="true"
              outputType="both"
              (imageCropped)="imageCropped($event)"
              (imageLoaded)="imageLoaded()"
              (cropperReady)="cropperReady()"
              (loadImageFailed)="loadImageFailed()"></image-cropper>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-sm btn-secondary"
              (click)="cancelCrop()">Cancel</button>
            <button type="button" class="btn btn-sm btn-primary"
              (click)="crop()">Crop</button>
          </div>
        </div>
      </div>
    </div>

使用该sourceImage物业是做我想做的事情的正确方法吗?我更改了this.lastCroppedImage唯一的内部crop() 方法。但是,只要在文件输入中选择新图像,它似乎就会发生变化。为什么会这样?

PS:我已经尝试过sourceImage直接分配而不创建新的ElementRef. 那也行不通。

Stackblitz 示例:https ://stackblitz.com/edit/image-cropper-r5pyqh

在 Stackblitz 中重现的步骤:

Browse and crop an image.
Browse again and select new image.
Click cancel in the crop window.
Click recrop. Observe that the image in crop window is the second one. Instead I want the first one.
4

2 回答 2

1

您可以创建一个变量来存储以前的图像,当您想要重新裁剪时,只需将其分配给src图像。让我举个例子:

ImageCropperComponent.ts:

@Input() imgToBeSet: any;
@Input() showPrevImage: false;
@Output() cropperReady = new EventEmitter<any>();

ngOnChanges(changes: SimpleChanges): void {
    if (this.imgToBeSet && this.showPrevImage){
      console.log('***** set prev image');
      this.safeImgDataUrl = this.imgToBeSet;
    }  
}

应用组件.ts

currentImgUrl: any;
recropImage: false;

reCrop() {
    this.logoModal.show();
    this.recropImage = true;
}

cropperReady(eventArgs: any) {
    if (!this.currentImgUrl) {
        this.currentImgUrl = eventArgs.currentImgUrl;
        console.log(`currentImgUrl is`, this.currentImgUrl);
    }
}

应用组件.html

<div class="modal-body">
    <image-cropper
    #imageCropper
      [imageChangedEvent]="imageChangedEvent"
      [maintainAspectRatio]="true"
      [aspectRatio]="4 / 3"
      [autoCrop]="false"
      [imgToBeSet] = "currentImgUrl"
      [showPrevImage] = "recropImage"
      onlyScaleDown="true"
      outputType="both"
      (imageCropped)="imageCropped($event)"
      (imageLoaded)="imageLoaded()"
      (cropperReady)="cropperReady($event)"
      (loadImageFailed)="loadImageFailed()"></image-cropper>
  </div>

完整的例子可以在 stackblitz 上看到

于 2019-12-17T09:26:24.503 回答
0

请使用一个函数来重置它, 如:

   resetImage() {
        this.scale = 1;
        this.rotation = 0;
        this.canvasRotation = 0;
        this.transform = {};
    }

在这里,我添加了stackblitz以便您了解。

于 2020-04-15T13:39:30.950 回答