Image cropping plugin

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

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).

1 Like

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

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;
2 Likes

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.

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.

2 Likes

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

1 Like

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.

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.

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.

Actually I didn’t used these buttons and preview in my own project so I don’t really have a working example to help you.

To get the result, there I could help :wink:

Define a method like following to be called once the user is happy with his cropped picture. The string result gonna be a Base64 string image. Also you could notice that you could define the size of the picture you want back.

 select() {
    let croppedImgURI:string = this.cropper.getCroppedCanvas({
        width: 1080,
        height: 1080
    }).toDataURL('image/jpeg', (85 / 100));

  // Navigate or do your upload here
}

Note: (85 / 100) is 0.85 aka the jpeg quality you want to use.

Hi @reedrichards,

I couldn’t get this to work. I get an error when trying to instantiate a cropper:

TypeError: Cropper is not a constructor

Did you need to include jQuery to get this to work?

I did make a few changes compared to your post, which I assume were just typos:

  3. import * as Cropper from 'cropperjs';
  5. @import "cropper.css";

Here is my source:

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Camera } from 'ionic-native';

import * as Cropper from 'cropperjs';

@Component({
    templateUrl: 'build/pages/player-settings/crop-photo.html',
})
export class CropPhoto {
    @ViewChild('imageSrc') input: ElementRef;
    private imageUri: string = 'img/test.jpg';
    private cropper: cropperjs.Cropper;

    constructor(private nav: NavController) {
    }

    imageLoaded() {
        console.log("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) => {
            }
        });
    }
}

Thanks in advance.

No I don’t include jquery.

Your code seems to be ok.

In the html code, did you also set the ‘#imageSrc’ to retrieve the @ViewChild(‘imageSrc’)?

Did you get the error at runtime or at compilation time?

Yes, I have the imageSrc set:

<ion-header>

  <ion-navbar>
    <ion-title>Crop Photo</ion-title>
  </ion-navbar>

</ion-header>

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

It is a runtime error, when I run in the browser or on my android emulator.

I am using the following versions:

cropperjs: 0.81
ionic-angular: 2.0.0-beta.10
angular: 2.0.0-rc.3

I’m using:

"cropperjs": "^0.7.2"
"ionic-angular": "^2.0.0-beta.11"
"@angular/core": "^2.0.0-rc.4"

I had a look at your code, only difference I saw is that I declare imageUri as public not private and you initialize imageUri with ‘img/test.jpg’ where I work with base64 images ('data:image/jpeg;base64,…). Could that be the problem? Maybe when you run the code ‘img/test.jpg’ isn’t found and cropper could not contruct an object because of that reason?

Hey @Oldstadt, I tried to use cropperjs version 0.8.1 and I had the same problem at runtime than you aka the same error

 TypeError: Cropper is not a constructor

I didn’t try that much to correct the error. The first problem I saw is that they seems to have migrated to less. Therefore the import of sass isn’t possible anymore. Tried to import the css file, I wasn’t that successful. Furthermore they might be some code change needed too.

So personally right now I gonna stick to version 0.7.2. If you are successful I would like to hear about it :wink:

Thanks @reedrichards,

I think I will give that version a try. In the mean time I played around with ng2-img-cropper, which I managed to get working, even though it doesn’t look as good as cropperjs. Importantly, it does support fixed aspect ratios.

Have the following issue, hope you could help me.
I’ve followed the instructions step by step, but when doing ionic serve typescript says that it couldn’t find the module.

//ImageCropper
import * as Cropper from 'cropperjs';
@Component({
  templateUrl: 'build/pages/messenger/messenger.component.html',
  providers: [MessengerService]
})
export class MessengerPage {
  @ViewChild('imageSrc') input: ElementRef;

    constructor() {
    }
    // Image crop method
      imageLoaded() {
        let 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: (event:cropperjs.CropperCustomEvent) => {
              console.log(event);
            }
        });
        }
    }

///HTML///
<img (load)="imageLoaded()" [src]="img" #imageSrc/>

Don’t know whats happening, in app.core.scss had to use @import “cropper.css” because cropper.scss also throws and error in typescript

Which version of cropperjs did you install?

With @Oldstadt we discovered this week that that “how to” isn’t valid for the last version of cropperjs (0.8.1) but works for version 0.7.2.

i’ve installed 0.7.2 as you said, but ionic serve in command line tells me that typescript could not find a module ‘cropperjs’ neither a namespace called ‘cropperjs’ so i don’t know what to do, and i really really need to use this plugin to work.

Also the typings install doesn’t gave me an error :pensive: