简体   繁体   English

ngx-image-cropper:将源图像重置为之前裁剪过的图像

[英]ngx-image-cropper: Reset the source image to previously cropped image

I am using the ngx-image-cropper library for cropping images in my Angular 8 project.我正在使用ngx-image-cropper库在我的 Angular 8 项目中裁剪图像。

What I want to do is:我想做的是:

  • I want to show the cropper inside a modal on selecting a file.我想在选择文件时在模式中显示裁剪器。
  • The modal has a crop button on clicking which the image will be cropped (no autocrop) and a cancel button which can be used to close the modal without cropping the image.模态有一个裁剪按钮,单击该按钮将裁剪图像(无自动裁剪)和一个取消按钮,可用于关闭模态而不裁剪图像。
  • After the image is cropped, the modal will be closed and there will be an edit button which can be used to recrop the image (On clicking crop, I essentially crop the image and hide the modal. So on clicking edit, I just show the hidden modal again.).裁剪图像后,模态将关闭,并且将有一个编辑按钮可用于重新裁剪图像(单击裁剪时,我基本上裁剪图像并隐藏模态。因此,单击编辑时,我只显示再次隐藏模态。)。
  • If another file is selected from the file input, the modal will be shown with the new image.如果从文件输入中选择了另一个文件,模态将与新图像一起显示。 The user can either crop or cancel.用户可以裁剪或取消。 If it is cancelled, I want to reset the source image of the cropper to the previous image.如果取消,我想将裁剪器的源图像重置为上一个图像。 How can I do that?我怎样才能做到这一点?

I have tried the following, but doesn't work:我尝试了以下方法,但不起作用:


    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 Code: 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>

Is using the sourceImage property the right way to do what I want to do?使用sourceImage属性是做我想做的事情的正确方法吗? I change the this.lastCroppedImage only inside crop() method.我只在crop() 方法中更改this.lastCroppedImage But it seems to be changing whenever a new image is selected in the file input.但每当在文件输入中选择新图像时,它似乎都会发生变化。 Why does that happen?为什么会这样?

PS: I have already tried assigning the sourceImage directly without creating a new ElementRef . PS:我已经尝试过直接分配sourceImage而不创建新的ElementRef That doesn't work either.那也行不通。

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

Steps to reproduce in Stackblitz:在 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.

You can create a variable to store a previous image and when you want to recrop, then just assign it to the src of an image.您可以创建一个变量来存储以前的图像,当您想要重新裁剪时,只需将其分配给图像的src Let me show an example:让我举个例子:

ImageCropperComponent.ts: 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;
    }  
}

AppComponent.ts : AppComponent.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);
    }
}

AppComponent.html : AppComponent.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>

The complete example can be seen here at stackblitz . 完整的例子可以在 stackblitz 看到

Please use a function to reset it like:请使用一个函数来重置它,如:

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

Here I added stackblitz so you get an idea.在这里,我添加了stackblitz以便您了解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM