Image cropping plugin


#12

Thanks maxx0r, I just tested it on my device and it works.

I have been struggling with this, to thank you.


#13

Great :slight_smile: I’ve been there too, glad I could help.


#14

did you found a plugin or script for cropping base64 image @richardmarais?


#15

I do the following. It takes a photo or allows picking from gallery depending on PictureSourceType, and then crops the image and saves as base64.

import { Camera } from 'ionic-native';
    takePhoto(pictureSourceType) {
        this.takeThePhoto(navigator.camera.PictureSourceType.CAMERA);
    }
    pickImage() {
        this.takeThePhoto(navigator.camera.PictureSourceType.SAVEDPHOTOALBUM);
    }
    takeThePhoto(pictureSourceType) {
        Camera.getPicture({
            sourceType: pictureSourceType,
            destinationType: Camera.DestinationType.FILE_URI,
            quality: 50,
            targetWidth: 720,
            correctOrientation: true,
            encodingType: Camera.EncodingType.JPEG
        })
            .then(
            imageURI => {
                window['plugins'].crop.promise(imageURI, {
                    quality: 75
                }).then(newPath => {
                        return this.toBase64(newPath).then((base64Img) => {
                            this.base64Image = base64Img;
                        });
                    },
                    error => {
                        console.log("CROP ERROR -> " + JSON.stringify(error));
                        alert("CROP ERROR: " + JSON.stringify(error));
                    }
                    );
            },
            error => {
                console.log("CAMERA ERROR -> " + JSON.stringify(error));
                alert("CAMERA ERROR: " + JSON.stringify(error));
            }
            );
    }
    toBase64(url: string) {
        return new Promise<string>(function (resolve) {
            var xhr = new XMLHttpRequest();
            xhr.responseType = 'blob';
            xhr.onload = function () {
                var reader = new FileReader();
                reader.onloadend = function () {
                    resolve(reader.result);
                }
                reader.readAsDataURL(xhr.response);
            };
            xhr.open('GET', url);
            xhr.send();
        });
    }
    resize(base64Img, width, height) {
        var img = new Image();
        img.src = base64Img;
        var canvas = document.createElement('canvas'),ctx = canvas.getContext('2d');
        canvas.width = width;
        canvas.height = height;
        ctx.drawImage(img, 0, 0, width, height);
        return canvas.toDataURL("image/jpeg");
    }

#16

Thx a lot for sharing the code, works really well.

Did you also find a way to specify the size (width/height) of the cropped image?


#17

Here you go:

> this.base64Image = this.resize(this.base64Image, 150, 150);


Camera, ImagePicker permission to access media
#18

Cool thx, I should had scroll before.

Tried but somehow my images wasn’t resized correctly.

I didn’t search that much longer because I’m also not sure that this plugin is the solution for my app. I would also like to have a fixed aspect ratio of the “cropper selector” which is actually not possible (https://github.com/jeduan/cordova-plugin-crop/issues/8)


#19

I am getting a permission error Not allowed to load local resource: file:///storage/emulated/0/Android/data/......
any idea’s?


#20

I’m not sure where you are running it, but it doesn’t work in a browser. Do a cordova build and install the apk on your device.


#21

i’m running in emulator, the error fixes when i dont run with -l -c … when i run without it works fine.


#22

For the record, I’m back at testing the cordoba-plugin-crop.
On Android 6 Nexus I face a 404 error which doesn’t seems to be solved yet


#23

Ok so for the record, I ended up not using cordoba-plugin-crop but I used cropperjs instead

https://fengyuanchen.github.io/cropperjs/

The integration in Ionic2 is ok and it runs pretty smooth on both Android and iOS device (even iPhone 4s).
Furthermore I could accomplish my wish to crop images only to square images (aspect ratio 1/1).


#24

Hi @reedrichards,
How did you get cropperjs plugin to work (inside your .ts) after camera taking the picture or choosing from your image gallery ?

Thanks in advance


#25

After taking the picture with the camera or selecting an image from the gallery.

When I get the result I parse it in a class variable

Camera.getPicture(options).then((imageData:string) => {
        this.imgURI = 'data:image/jpeg;base64,' + imageData;
}, (err:string) => {
     console.error(err)
    });

Then in the html, when the variable is not null I display it

 <ion-item *ngIf="imgURI != null">
     <img (load)="imageLoaded()" [src]="imgURI" #imageSrc>
  </ion-item>

and you could notice that then, when the image is loaded, I call a method which gonna initialize cropper

imageLoaded() {
    this.cropper = new Cropper(this.input.nativeElement, {
        aspectRatio: 1 / 1,
        dragMode: 'move',
        modal: true,
        guides: true,
        highlight: false,
        background: true,
        autoCrop: true,
        autoCropArea: 0.9,
        responsive: true,
        crop: (e:cropperjs.CropperCustomEvent) => {

        }
    });
}

Note that the input should be instanced as a Viewchild to use it in the Cropper constructor

 @ViewChild('imageSrc') input: ElementRef;

#26

hi @reedrichards,

Could u please give us instruction how to install cropperjs into ionic2 with ts ?
ex. where to copy the js file ?, do i have to import it ?, how to declare the Cropper ?
Thanks in advance.


#27

Here how I proceeded:

  1. Install cropperjs (*** Update: Install version 0.7.2. Later version, like 0.8.1, doesn’t seems to be compatible anymore with my “how to”)

    sudo npm install cropperjs --save

  2. Install the typescript definition for cropperjs

    typings install dt~cropperjs --save --global

  3. In your ts class file, include cropperjs

    import * as Cropper from ‘croppers’;

  4. And finally declare a cropper variable in your class

    private cropper:cropperjs.Cropper;

  5. (Update) Also don’t forget to include the cropperjs css file in your project otherwise the cropperjs element not gonna be displayed correctly at runtime. Therefor add in your app.core.scss

    @import “cropper.scss”;

For the rest you could go on with my previous post.


#28

It worked like a charm to me!
Thanks for the help…


#29

Hi @reedrichards ,

I try above but with different way…

`takePhotoLibrary() {
        this.platform.ready().then(() => {
        Camera.getPicture({
            destinationType: Camera.DestinationType.FILE_URI,
            sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
            correctOrientation: true
        }).then((imageURI) => {
            this.currentImage = imageURI;
            
            this.doImageCrop(this.currentImage, (dataCrop) => {
                  this.imageCrop = dataCrop;
                  console.log('this.imageCrop', this.imageCrop);
            });
        }, (err) => {
            console.log(err);
            
        });  // getPicture
        }); // platform.ready
    }

doImageCrop(img, callback) {
        var cropper = new Cropper(img, {
            aspectRatio: 1 / 1,
            dragMode: 'move',
            autoCrop: true,
            autoCropArea: 0.9,
            crop: function(e:cropperjs.CropperCustomEvent) {
                console.log(e.detail.x);
                console.log(e.detail.y);
                console.log(e.detail.width);
                console.log(e.detail.height);
                console.log(e.detail.rotate);
                console.log(e.detail.scaleX);
                console.log(e.detail.scaleY);
                //callback(e);
            }
});` 

and then i got an error like this…
EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property ‘toLowerCase’ of undefined

Any suggestion and help ???
Thks.


How to make ionic native Crop spit out base64 data instead of path?
#30

I found, I guess, one problem. Don’t know if it’s the source of the error msg you have got, but:

Your Cropper instantiation can’t work I think. You do:

 var cropper = new Cropper(img, {

where “img” is the FILE_URI of your returned image on the device. This ain’t work I think. To initialize cropper your should pass a reference to the GUI/Html component. In my case I did:

 this.cropper = new Cropper(this.input.nativeElement, {

For understanding, in angular 1 it would had been something like ‘document.getElementById…’

Again don’t know if it’s the source of your error but maybe give a try.


#31

Thanks @reedrichards,

It works now… and yes… To initialize cropper we should pass a reference to the GUI/Html component and not FILE_URI of the returned image from device.

Could you help me again to show how to put button click like move, crop, zoom, rotate and preview the cropped result at the same page just like fengyuanchen’s sample photo editor.

Also how to get the result so I can upload it to the server…
Thanks in advance.