Image previewing problem after cropping in Angular 10

2k Views Asked by At

in my angular 10 project I have used ngx-image-cropper to crop image. After crop the image ngx-image-cropper gives us base64 string value. But I want to convert this base64 value to file and show this file in another image previewer. Later I want to upload that converted image to server rather saving base64 to database. To convert base64 to image file I have used the below code:

convertBase64ToFile(data, filename) {
    const arr = data.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);

    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }

    return new File([u8arr], filename, { type: mime });
  }

Now in imageCropped event, I tried to set that converted image file to a image previewer. the code is:

imageCropped(event: ImageCroppedEvent) {
    this.croppedImage = event.base64;
    
    this.fileToReturn = this.convertBase64ToFile(event.base64, this.imageChangedEvent.target.files[0].name)

    console.log(this.fileToReturn);
    
    var reader = new FileReader();
    reader.onload = (event: any) => {
      this.croppedImage = this.fileToReturn;
    };

    reader.onerror = (event: any) => {
      console.log("File could not be read: " + event.target.error.code);
    };

    reader.readAsDataURL(this.fileToReturn);

    return this.fileToReturn;
  }

If I print this variable fileToReturn value to console I get the below object:

enter image description here

The HTML :

<div id="preview" class="text-center col-md-4">
   <h5>Preview</h5>
   <img [src]="croppedImage" />
</div>

But the problem is image is not showing. Instead I get the below message in Console:

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

Now can anyone suggest me

  1. how to show the converted file to the previewer
  2. how to upload the converted file to server?

My full code is:

<div class="container">
    <div class="row" style="margin-top: 5%;">
        <div class="text-center col-md-12">
            <input type="file" (change)="fileChangeEvent($event)" />
        </div>
    </div>
    <div class="row" style="margin-top: 5%;">
        <div class="text-center col-md-8">
            <h5>Crop Image</h5>
            <image-cropper 
                [imageChangedEvent]="imageChangedEvent" 
                [maintainAspectRatio]="true" 
                [aspectRatio]="4 / 4"
                [resizeToWidth]="256" 
                format="png" 
                (imageCropped)="imageCropped($event)" 
                (imageLoaded)="imageLoaded()"
                (cropperReady)="cropperReady()" 
                (loadImageFailed)="loadImageFailed()">
            </image-cropper>
        </div>
        <div id="preview" class="text-center col-md-4">
            <h5>Preview</h5>
            <img [src]="croppedImage" />
        </div>
    </div>
</div>

TS file:

import { Component, OnInit } from '@angular/core';
import { ImageCroppedEvent } from 'ngx-image-cropper';

@Component({
  selector: 'app-image-cropper1',
  templateUrl: './image-cropper1.component.html',
  styleUrls: ['./image-cropper1.component.css']
})
export class ImageCropper1Component implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

  imageChangedEvent: any = '';
  croppedImage: any = '';
  fileToReturn: any;

  fileChangeEvent(event: any): void {
    this.imageChangedEvent = event;
    //console.log(event);

  }

  imageCropped(event: ImageCroppedEvent) {
    this.croppedImage = event.base64;
    this.fileToReturn = this.convertBase64ToFile(event.base64, this.imageChangedEvent.target.files[0].name)

    //console.log(this.imageChangedEvent.target.files[0]);
    console.log(this.fileToReturn);
    
    var reader = new FileReader();
    reader.onload = (event: any) => {
      this.croppedImage = this.fileToReturn;
    };

    reader.onerror = (event: any) => {
      console.log("File could not be read: " + event.target.error.code);
    };

    reader.readAsDataURL(this.fileToReturn);

    return this.fileToReturn;
  }

  imageLoaded() {
    // show cropper
  }

  cropperReady() {
    // cropper ready
  }

  loadImageFailed() {
    // show message
  }

  convertBase64ToFile(data, filename) {
    const arr = data.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);

    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }

    return new File([u8arr], filename, { type: mime });
  }
}
1

There are 1 best solutions below

2
On

To convert cropped image as a file instead of a base64 string ngx-image-cropper have base64ToFile method

imageCropped(event: ImageCroppedEvent) {
    this.croppedImage = event.base64;
    let File = base64ToFile(this.croppedImage);
}