Nimish David Mathew
Nimish David Mathew

Reputation: 3168

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.

What I want to do is:

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:

    <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? I change the this.lastCroppedImage only inside crop() method. 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. That doesn't work either.

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

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

Upvotes: 2

Views: 8210

Answers (2)

Manish Patidar
Manish Patidar

Reputation: 804

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.

Upvotes: 0

StepUp
StepUp

Reputation: 38124

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. Let me show an example:

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:

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:

<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.

Upvotes: 1

Related Questions