How do I select an image to import it to manipulate with `cropper.js` plugin in angular?

Viewed 328

I intended to import an image to my angular application and manipulate it with croppers.js plugin. I can address an image with relative address and image will be shown properly but when I import an image with file input type, my application can not detect the image and raises an error.

My codes are listed below:

.html file:

<div class="originalImage">
    <img #image [src]="imageSource" >
</div>
<div>
    <img [src]="imageDestination" class="editedImage">
</div>

<button mat-raised-button (click)="openInput()">Select File to Upload</button>
<input id="fileInput" hidden type="file" (change)="fileChange($event)" name="file" accept=".jpg,.jpeg,.png">

.ts file:

import { Component, OnInit, ViewChild, Input, ElementRef, AfterViewInit } from '@angular/core';
import Cropper from 'cropperjs';

@Component({
selector: 'app-pictures',
templateUrl: './pictures.component.html',
styleUrls: ['./pictures.component.scss']
})

export class PicturesComponent implements OnInit, AfterViewInit {
    @ViewChild("image", {static: false})
    public imageElement: ElementRef;
    public imageSource: string;
    public imageDestination: string;
    private cropper: Cropper;

    constructor() {
        this.imageDestination = '';
    }

    ngOnInit() {
        this.imageSource = '/assets/images/greg-cohen-3928.jpg';
    }

    public ngAfterViewInit(): void {
        this.cropper = new Cropper(this.imageElement.nativeElement, {
        viewMode:2,
        zoomable: true,
        scalable: true,
        cropBoxResizable: true,
        });
        
    }

    public cropIt() {
        console.log('start-crop');

        const canvas = this.cropper.getCroppedCanvas({
        minWidth: 256,
        minHeight: 256,
        maxWidth: 4096,
        maxHeight: 4096,
        fillColor: '#f0f',
        imageSmoothingEnabled: true,
        imageSmoothingQuality: 'high',
        });
        this.imageDestination = canvas.toDataURL("image/jpeg");
    }

    public openInput(){ 
        document.getElementById("fileInput").click();
    }

    public fileChange(x){
        this.imageSource = x.target.files[0]; 
    }
}

As you can see in the .ts file I addressed an image with relative URL in ngOnInit() and it shows the image correctly.

The problem starts when I selected new image for editing but it didn't replace old image with the new one and raises below error in console:

GET http://localhost:2281/[object%20File] 404 (Not Found)

I don't know how to import new image and replace it. what's your idea?

3 Answers

you just have to change your filechange function to

 public fileChange(x) {
    if (x.target.files.length >= 1) {
      var reader = new FileReader();
      reader.onload = f => {
        this.imageSource = f.target.result;
      };
      reader.readAsDataURL(x.target.files[0]); // calls onload
    }
  }

do let me know still you have a problem with import file..

Thanks

Change your file change function to

public fileChange(event: Event) {
       const file =  (event.target as HTMLInputElement).files[0];
       const reader = new FileReader();
       reader.onload = () => {
       const preview = reader.result as string;
    }
     reader.readAsDataURL(file);
    }

Do this bro:

.html

<input type="file (change)="fileChangeEvent($event)" />
<div class="img-container">
    <img #imageCropper [src]="imageSource" crossorigin alt="image cropper">
</div>
<img [src]="imageDestination" class="img-preview" alt="image result">

.ts (No need for the ngAfterViewInit):

export class YourComponent {
    @ViewChild('imageCropper', { static: false })
    imageElement: ElementRef;
    imageSource: any = 'assets/images/bankwide-recon-icon.jpg';
    imageDestination = '';
    cropper: Cropper;

    constructor(
        private changeDetectorRef: ChangeDetectorRef,
    ) { }

    fileChangeEvent(event) {
        if (event.target.files && event.target.files[0]) {
            const reader = new FileReader();
            reader.onloadend = (e: any) => {
                this.imageSource = e.target.result;
                this.changeDetectorRef.detectChanges(); // Haven't tried out without this line
                if (this.cropper) { // Haven't tried out without this if block
                    this.cropper.destroy();
                }
                this.cropper = new Cropper(this.imageElement.nativeElement, {
                    crop: () => {
                        const canvas = this.cropper.getCroppedCanvas();
                        this.imageDestination = canvas.toDataURL('image/png');
                    }
                });
            };
            reader.readAsDataURL(event.target.files[0]);
        }
    }
}

and the .css:

@import "~cropperjs/dist/cropper.min.css";

.img-container {
    width: 720px;
    height: 720px;
    float: left;
    border: 2px solid #e99158;
}

.img-preview {
    width: 200px;
    height: 200px;
    float: left;
    margin-left: 10px;
    border: 2px solid #e99158;
}

Please reach me if there's any problem

Related