Srijib Mandal
Srijib Mandal

Reputation: 605

how to combine ngx-compress-image and ngx-image-cropper

I want to upload an image, by letting user to select using input[type=file]compress it , have a preview and then let user crop the image and post it to API endpoint

<input type='file' onchange='compress($event)> do far I am able to select the image and compress it via ngx-compress-image the compress image is being shown in the preview. but now i want to pass this compressed image to ngx-image-cropper which expects a FileEvent event. how do i problematically pass the compressed image

<input type="file" (change)="fileChangeEvent($event)" />

<image-cropper
    [imageChangedEvent]="imageChangedEvent"
    [maintainAspectRatio]="true"
    [aspectRatio]="4 / 3"
    format="png"
    (imageCropped)="imageCropped($event)"
    (imageLoaded)="imageLoaded()"
    (cropperReady)="cropperReady()"
    (loadImageFailed)="loadImageFailed()"
></image-cropper>

<img [src]="croppedImage" />

Upvotes: 2

Views: 1327

Answers (3)

Am Semity
Am Semity

Reputation: 1

enter code here
I tried to use ngx-image compress,but the output file size is not of much difference than original. Then i relied on reducing the file size by math calculations manually. The function goes like below 




croppedPicture: {
    src: string;
    size: string;
  } = {
    src: '',
    size: '',
  };

  /**function that crops selected image and emits event with properties like blob,base64*/
  imageCropped(event: any) {
    // the cropped image event has blob(sent to fire storage)
    // and base64 (used in fileSize reduction)
    // then base64String (used for display as croppedPicture.src)
    this.croppedImage = event.blob;
    const transformedImage = {
      src: event.base64,
      size: this.getFileSize(event.base64),
    };
    this.croppedPicture = transformedImage;

    const reader = new FileReader();
    reader.onloadend = () => {
      const base64String = reader.result as string;
      this.croppedPicture.src = base64String;
    };
    reader.readAsDataURL(event.blob);
  }

  getFileSize(src: string): string {
    // Accommodating padding characters to arrive at the standard length of base64 ie multiple of 4
    if (src) {
      const base64Length = src.length - (src.indexOf(',') + 1);
      const padding =
        src.charAt(src.length - 2) === '='
          ? 2
          : src.charAt(src.length - 1) === '='
          ? 1
          : 0;
      // in base64 length of characters, set of 4ch occupy 3 bytes, each byte with 8 bit data
      //(3/4=0.75); converting bytes to kb(/1024); removing that extra padding for std length which is not actual content of img
      const reducedFileSize = ((base64Length * 0.75 - padding) / 1024).toFixed(
        0
      );
      return reducedFileSize + 'KB';
    }
    return '0KB';
  }

Upvotes: 0

Zia Khan
Zia Khan

Reputation: 425

Very simple. After the user finish cropping , then by saving/submitting it must pass through compression phase like ngx-compression

Upvotes: 0

Srijib Mandal
Srijib Mandal

Reputation: 605

In case someone else would look a solution to combine these plugins. The cropper plugging has other @Inputs() exposed as well. so i used the base64 like below.

<image-cropper
    [imageBase64]="ImageToCrop" // <----- added this
    [maintainAspectRatio]="true"
    [aspectRatio]="4 / 3"
    format="png"
    (imageCropped)="imageCropped($event)"
    (imageLoaded)="imageLoaded()"
    (cropperReady)="cropperReady()"
    (loadImageFailed)="loadImageFailed()"
></image-cropper>

<img [src]="croppedImage" />

Upvotes: 1

Related Questions