I'm using ng-file-upload to preview and upload an image. Before I upload the image I'd like to have the user crop the image. I tried using ng-img-crop, but that didn't have the features I wanted (aspect ratio customization), but cropper did (https://github.com/fengyuanchen/cropper/). My only problem now is how can I crop a preview of an image using cropper. The image src ends up being a blob ie "blob:XYZ". Has anyone successfully used cropper in this way? Is it possible?
this.cropper.getCroppedCanvas().toBlob()
by attaching it to the state.File
constructor within the save()
function by pushing it to the first parameter fileBits
multer
import { AfterViewInit, Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { default as Cropper } from 'cropperjs';
import { FileItem, FileUploader } from 'ng2-file-upload';
import { UserService } from '../services/user.service';
import { User } from '../models/core';
@Component({
selector: 'app-image-cropper',
templateUrl: './image-cropper.component.html',
styleUrls: ['./image-cropper.component.scss']
})
export class ImageCropperComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('imageElement', {static: false})
public imageElement: ElementRef;
@Input()
public imageSource: string;
public imageBlob: Blob;
public uploader: FileUploader;
private cropper: Cropper;
public constructor(private userService: UserService) {}
public ngAfterViewInit() {
this.cropper = new Cropper(this.imageElement.nativeElement, {
zoomable: false,
scalable: false,
responsive: true,
autoCropArea: 1,
aspectRatio: 1,
viewMode: 1,
crop: (event) => {
this.cropper.getCroppedCanvas().toBlob((blob) => {
this.imageBlob = blob;
console.log('Crop saved as a Blob');
});
}
});
}
public save() {
const date: number = new Date().getTime();
// Put the blob into the fileBits array of the File constructor
const file = new File([this.imageBlob], 'photo', {type: 'image/png', lastModified: date});
const fileItem = new FileItem(this.uploader, file, {});
this.uploader.queue.push(fileItem);
fileItem.upload();
}
ngOnInit() {
this.userService.user$.subscribe((user: User) => {
this.uploader = new FileUploader({url: '/api/profile/' + user.username + '/avatar', itemAlias: 'photo'});
this.uploader.onAfterAddingFile = (file) => {
file.withCredentials = false;
};
this.uploader.onCompleteItem = (item: any, response: any, status: any, headers: any) => {
console.log(response);
};
});
}
ngOnDestroy(): void {
this.imageBlob = undefined;
this.imageSource = '';
}
}
<div class="modal-content">
<div class="modal-header">
<p class="modal-title font-weight-bold" id="crop-modal-title"><i></i>Crop</p>
<button type="button" class="close" data-dismiss="modal"
(click)="activeModal.close('Close click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="img-container">
<img #imageElement [src]="imageSource" crossorigin>
</div>
<button type="button" class="button button-primary"
(click)="save()">
</button>
</div>
</div>
import { Request, Response, Router } from 'express';
import * as util from 'util';
import * as fs from 'fs';
import * as multer from 'multer';
Router.post('/profile/:username/avatar/', upload.single('photo'), async (req: Request, resp: Response) => {
try {
console.log(req.file);
// Do something with the uploaded file here
const fsUnlinkPromisified = (util as any).promisify(fs.unlink);
await fsUnlinkPromisified(req.file.path);
} catch (error) {
console.log(error);
return resp.send({
msg: 'Upload failed',
status: 400
});
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With