So I am facing with an error which it doesn't send the cropped image to the backend with multer.
I can upload the file in frontend and then I crop the image but the cropped image is not sent in the backend, but it is the uploaded img sent to the backend.
I am using the cropper.js
at Angular 11 version with a module that someone did develop for Angular.
this is the cropper.js
https://fengyuanchen.github.io/cropperjs/
And this is the module https://github.com/matheusdavidson/angular-cropperjs
So my idea it is like this. Upload photo -> crop it and save it in a folder at backend. The save works but it saves the default img not the cropped img. When user uses click event to saveImage , take the cropped image and save it in the backend.
This is my UI and methods.
<angular-cropper #angularCropper
[cropperOptions]="imgConfig"
[imageUrl]="imgUrl | safeurl"></angular-cropper>
<div class="btn-group">
<label class="btn btn-primary btn-upload" for="inputImage" title="Upload image file" >
<input type="file" class="sr-only" id="inputImage" name="file" accept="image/*" (change)="fileChangeEvent($event)">
<span class="docs-tooltip" data-toggle="tooltip" title="" data-original-title="Import image with Blob URLs">
<span class="fa fa-upload"></span>
</span>
</label>
</div>
<button type="button" class="btn btn-primary" data-method="crop" title="Crop" (click)="saveImage()">
<span class="docs-tooltip" data-toggle="tooltip" title="" data-original-title="cropper.crop()">
<span class="fa fa-check"></span>
</span>
</button>
TS file
imgUrl;
imageURL;
imageCrop;
@ViewChild("angularCropper", {static: false}) public angularCropper: CropperComponent;
public imgConfig = {
aspectRatio : 3/4,
dragMode : "move",
background : true,
movable: true,
rotatable : true,
scalable: true,
zoomable: true,
viewMode: 1,
checkImageOrigin : true,
checkCrossOrigin: true,
width: 0,
height: 0,
};
fileChangeEvent(event: any): void {
this.imgUrl = URL.createObjectURL(event.target.files[0]);
this.imageCrop = event.target.files[0];
}
saveImage() {
this.angularCropper.cropper.crop();
this.imageService.addImage(this.imageCrop).subscribe((res: any) => {
if (res.body) {
this.imageService.getImageByID(res.body._id).subscribe((t: Image) => {
this.imageURL = t.imageUrl;
console.log(this.imageURL);
});
}
}, (err: any) => {
console.log(err);
});
}
And this is my service
@Injectable({
providedIn: "root"
})
export class ImageService {
apiUrl = environment.backend;
constructor(private http: HttpClient) { }
addImage(file: File): Observable<any> {
const formData = new FormData();
formData.append("file", file);
const header = new HttpHeaders();
const params = new HttpParams();
const options = {
params,
reportProgress: true,
headers: header
};
const req = new HttpRequest("POST", `${this.apiUrl}/images/${file.name}`, formData, options);
return this.http.request(req);
}
getImageByID(id: string): Observable<any> {
const url = `${this.apiUrl}/${id}`;
return this.http.get<Image>(url).pipe(
catchError(this.handleError)
);
}
private handleError(error: HttpErrorResponse): any {
if (error.error instanceof ErrorEvent) {
console.error('An error occurred:', error.error.message);
} else {
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
return throwError(
'Something bad happened; please try again later.');
}
}
you will the cropped image from the output of cropper component.. export is the output name