Reputation: 605
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
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
Reputation: 425
Very simple. After the user finish cropping , then by saving/submitting it must pass through compression phase like ngx-compression
Upvotes: 0
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