Is there a way to adjust the brightness and contrast of the cropper image before I crop it with ngx-image-cropper and have those filters be applied when the image gets cropped?
EDIT 5/1/2024 – I know I can get the base64 image after I crop()
, create a canvas and apply CSS filters (it’s what I’m currently doing). But I would like to see if there is a way to do it before I crop()
or to the image that is being cropped, so as to avoid the labor of creating a new canvas with image after I crop just to alter CSS filter values, which were already done with the "imageCropper.sourceImage" on screen by the user. Here is an example of what I’m doing in the app.
// Called after the user changes a slider on screen to adjust the brightness
changeBrightness(event: any) {
this.filterApplied = true;
this.imageCropper.sourceImage.nativeElement.style.filter = 'brightness(' + event.target.value + '%) contrast(' + this.contrast + '%) saturate(' + this.saturate + '%)';
}
// Gets called when the user has visually inspected
// his image on screen and is ok with it and is
// ready to save it to the DB.
saveImage() {
if (this.filterApplied) {
const filteredImage = this.applyFilter(this.imageCropper.crop('base64').base64);
this.saveToDb(filteredImage);
} else {
this.saveToDb(this.imageCropper.crop('base64').base64);
}
applyFilter(base64) {
// code left out for brevity
// 1. create canvas and modify CSS filters
// 2. return base64 image
}
I can adjust the source image (image on screen) brightness, contrast and saturation (see above), but when I crop()
and then display the cropped image, the CSS that has been altered in the
immageCropper.sourceImage
doesn’t get used in the cropped image.
What I tried (see my snippet below) with no luck.
- Altered the imageCropper.sourceImage.nativeElement.style.filter
- Modified the loadedImage property from private to public and
a.) Altered the imageCropper.loadedImage.original.image.style.filter
b.) Altered the imageCropper.loadedImage.transformed.image.style.filter
I tried stepping through the libraries code to see what image was being used but got a little lost.
Here is a sample below of how I modify the CSS for the source image and my example on stackblitz code that shows what I’m doing.
@ViewChild("imageCropper") imageCropper: ImageCropperComponent;
crop() {
this.imageCropper.sourceImage.nativeElement.style.filter = 'brightness(150%) contrast(150%) saturate(150%)';
// I also tried loadedImage, both original and transformed with no luck
// this.imageCropper.loadedImage.original.image.style.filter = 'brightness(' + event.target.value + '%) contrast(' + this.contrast + '%) saturate(' + this.saturate + '%)';
// this.imageCropper.loadedImage.transformed.image.style.filter = 'brightness(' + event.target.value + '%) contrast(' + this.contrast + '%) saturate(' + this.saturate + '%)';
this.imageCropper.crop();
}
2
Answers
If you want to add the same filter to the cropped image after crop you can do the following :
1- declare the filter option you want like that:
2- Add a template reference to croppedImage :
3- Read this reference using
@ViewChild('corpImage')
:4- Inside the function
imageCropped
add a setTimeout and then add the filterOptions to the croppedImage:I don’t think adding CSS filter can change the filter inside of the image file itself, CSS will only add a "visual filter" on top of your image. I believe what you wanna do is to add filter to the "file" of the image right? If so, we can still use the same CSS rules that you have, but instead of applying it as a CSS filter, we can add it as a canvas filter.
The first thing you wanna do is to create this function:
The above function will do a similar thing as the cropping part, but this one is processing the image even before showing it. Basically when we get the
imageBase64
, we try to load it as anImage()
then when it’s loaded we draw it to the canvas in which we apply the CSS filter to.Once the image is drawn to the canvas, we then return it as parameter to
loadBase64Image()
function which will finally show the image, by adding this line after this line.then((resultBase64: string) => this.fitImageToAspectRatio(resultBase64))
:Technically it’s not CSS filter, it’s a property of canvas, but it accepts the same value as CSS filter.
Here is the forked stackblitz.