Hello everyone, here I bring you this Crop Image Android Tutorial in which you will learn how to implement image picker and cropper. This utillity can be used for configuring Profile Images or some image related tasks where you need to pick any image from gallery or camera and then get a cropped image out of it. So, without wasting any time, let’s get started.
The output of this Crop Image Android Tutorial may be seen in the below images.
Crop Image Android Tutorial
Creating new Project
- Begin with creating a new Android Studio Project. As the gradle is built and the files get loaded, we are good to import the library required to achieve the utility. To do so,
Adding Library
- Add the line below to your Project level gradle
1 2 3 | maven { url "https://jitpack.io" } |
- and add the line below to your app level gradle and sync it:-
1 2 3 | compile 'com.theartofdev.edmodo:android-image-cropper:2.3.+' |
- Now that the library has been imported.
Creating Interface
- Its time to configure the activity_main.xml and MainActivity.java.
- Here’s the activity_main.xml. It consists of an imageButton where you can tap on to load your profile picture and some textViews to display some profile information.
- So, go ahead and add the following code to your activity_main.xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@android:color/black"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Tap on the image below to change your profile picture" android:textColor="@android:color/white" android:textSize="20dp" android:id="@+id/textView" /> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/quick_start_cropped_image" android:background="@android:color/white" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:textColor="@android:color/black" android:layout_height="wrap_content" android:text="Name: Manish Kumar" android:textSize="30dp" android:layout_gravity="center" /> <TextView android:textColor="@android:color/black" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Email: manishh776@gmail.com" android:textSize="25dp" android:layout_gravity="center" /> <TextView android:textColor="@android:color/black" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="MobileNo:1234567890" android:textSize="25dp" android:layout_gravity="center" /> </LinearLayout> </FrameLayout> <ImageButton android:id="@+id/quick_start_cropped_image" android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/profile" android:layout_marginTop="39dp" android:layout_below="@+id/textView" android:layout_centerHorizontal="true" /> </RelativeLayout> |
Coding the Activity
- Now that the layout is configured, we shall configure the MainActivity.java.
- Here’s the MainActivity.java. It consists of methods to initiate the image selection, request permissions, handling the cropping activity and all. So, go ahead and add the following code to your MainActivity.java:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | package chutka.bitman.com.bestimagecropperever; import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.Toast; import com.theartofdev.edmodo.cropper.CropImage; import com.theartofdev.edmodo.cropper.CropImageView; public class MainActivity extends AppCompatActivity { ImageButton imageButton; /** * Persist URI image to crop URI if specific permissions are required */ private Uri mCropImageUri; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageButton = (ImageButton) findViewById(R.id.quick_start_cropped_image); imageButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onSelectImageClick(v); } }); } /** * Start pick image activity with chooser. */ public void onSelectImageClick(View view) { CropImage.startPickImageActivity(this); } @Override @SuppressLint("NewApi") protected void onActivityResult(int requestCode, int resultCode, Intent data) { // handle result of pick image chooser if (requestCode == CropImage.PICK_IMAGE_CHOOSER_REQUEST_CODE && resultCode == Activity.RESULT_OK) { Uri imageUri = CropImage.getPickImageResultUri(this, data); // For API >= 23 we need to check specifically that we have permissions to read external storage. if (CropImage.isReadExternalStoragePermissionsRequired(this, imageUri)) { // request permissions and handle the result in onRequestPermissionsResult() mCropImageUri = imageUri; requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0); } else { // no permissions required or already grunted, can start crop image activity startCropImageActivity(imageUri); } } // handle result of CropImageActivity if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) { CropImage.ActivityResult result = CropImage.getActivityResult(data); if (resultCode == RESULT_OK) { ((ImageButton) findViewById(R.id.quick_start_cropped_image)).setImageURI(result.getUri()); Toast.makeText(this, "Cropping successful, Sample: " + result.getSampleSize(), Toast.LENGTH_LONG).show(); } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) { Toast.makeText(this, "Cropping failed: " + result.getError(), Toast.LENGTH_LONG).show(); } } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { if (mCropImageUri != null && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // required permissions granted, start crop image activity startCropImageActivity(mCropImageUri); } else { Toast.makeText(this, "Cancelling, required permissions are not granted", Toast.LENGTH_LONG).show(); } } /** * Start crop image activity for the given image. */ private void startCropImageActivity(Uri imageUri) { CropImage.activity(imageUri) .setGuidelines(CropImageView.Guidelines.ON) .setMultiTouchEnabled(true) .start(this); } } |
- Next, we need an image to be displayed in the imageButton by default. To do so, save the image below and add it to the drawable folder of your project(filename must remain same).
- Great. We are almost done. Just update your AndroidManifest.xml with the one shown below:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="chutka.bitman.com.bestimagecropperever"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/Base.Theme.AppCompat"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity"/> </application> </manifest> |
- And you did it. Now run the project and tap on the profile image button. A pop up shall come up asking your to choose between Camera and Gallery. As you do and select the image, it shall take you to the CropImagActivity. Once cropped, it will return to the MainActivity with the cropped image set to the imageButton.
So thats all for this crop image android tutorial. If you are having any troubles regarding this crop image android tutorial the lets meet in the comment section to sort out the problems. Thank You 🙂
Hello, I am Manish Kumar. I am a B.Tech Student at NIT Jamshedpur. Fortunately, I find myself quite passionate about Computers and Technology. Android is my most recent Crush.
hi manish if i am uploding the file it showing error and it is possible we cant show only file explorer
if ok plz explain passible send code to mail or url
Thanks Manish .. you guys are doing a wonderful job here!!!
I wanted to upload the cropped image to the server as described in your tutorial below
https://www.simplifiedcoding.net/android-upload-image-to-server/
Files that are on the mobile work flawlessly however, the app crashes when I try to upload the camera image.
Seem the problem is that the camera returns a File URI and “content” which is being expected by the getPath method.
There seem to be some solutions below.
http://stackoverflow.com/questions/37624833/android-android-database-cursor-movetofirst-on-a-null-object-reference
http://stackoverflow.com/questions/6301215/converting-file-scheme-to-content-scheme/16916266#16916266
but my bad, am unable to make much sense of them.
Request your help, thanks in advance.
What is your exact exception that you are facing?
Manish .. am getting the following error
java.lang.NullPointerException: Attempt to invoke interface method ‘boolean android.database.Cursor.moveToFirst()’ on a null object reference
it is pointing to the “cursor.moveToFirst();” line in the getPath method ..
Hi Manish .. any solution?
It seems like the method used to get the path of the image in upload image post is not working in case of camera.
So,in the post on this link-https://www.simplifiedcoding.net/upload-pdf-file-server-android/ ,there’s a class called FilePath.java use that class to fetch the path of the image as you upload the image. Hope this will do.
Could you make a tutorial about upload image with mashmallow runtime permission?
@Dpotato
Add the following two methods to your activity and call requestStoragePermission() in OnCreate.
//Requesting permission
private void requestStoragePermission() {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
return;
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
//If the user has denied the permission previously your code will come to this block
//Here you can explain why you need this permission
//Explain here why you need this permission
}
//And finally ask for the permission
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
//This method will be called when the user will tap on allow or deny
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//Checking the request code of our request
if (requestCode == STORAGE_PERMISSION_CODE) {
//If permission is granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Displaying a toast
Toast.makeText(this, “Permission granted now you can read the storage”, Toast.LENGTH_LONG).show();
} else {
//Displaying another toast if permission is not granted
Toast.makeText(this, “Oops you just denied the permission”, Toast.LENGTH_LONG).show();
}
}
}
Thanks Manish, that worked
Thanks, Manish, for a wonderful tutorial but my problem here is I want the image to fit into a circle shape like a WhatsApp user profile. Secondly, it’s so small on my device after cropping and I’m trying to Crop the image and set it to the desired size but is not really working.
Hello pick from gallery is going out of my app please help me
everything worked fine at first but for some reason after some weeks when i try to pick from camera it just return, camera doesn’t open the piker just closes. picking from galary works just fine.
Camera is not opening on android marshMallow 6 and nouhgut 7, please help?
Nice tutorial
How to add an image field in my sql + php database and display it in Android Studio?
camera cropping is not working for galaxy s6 phone…but working in moto G4..
any solution for that?
CropImage.activity(imageUri)
.setGuidelines(CropImageView.Guidelines.ON)
.setMultiTouchEnabled(true)
.start(this);
here i have issues as my app crashes. i have added all the dependencies and maven libraries too. it just doesnt right the logs. Plus it never asks for the permissions too. how does it run anyway?
Hello everybody,
To those whoa re facing camera problems in marshmallow devices. The above code doesn’t check for camera runtime permissions. Here is the code
public void onSelectImageClick(View view) {
if (CropImage.isExplicitCameraPermissionRequired(this)) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, CropImage.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
} else {
CropImage.startPickImageActivity(this);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if (requestCode == CropImage.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
CropImage.startPickImageActivity(this);
} else {
Toast.makeText(this, “Cancelling, required permissions are not granted”, Toast.LENGTH_LONG).show();
}
}
if (requestCode == CropImage.PICK_IMAGE_PERMISSIONS_REQUEST_CODE) {
if (mCropImageUri != null && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// required permissions granted, start crop image activity
startCropImageActivity(mCropImageUri);
} else {
Toast.makeText(this, “Cancelling, required permissions are not granted”, Toast.LENGTH_LONG).show();
}
}
}
You can refer the sample code here
https://github.com/ArthurHub/Android-Image-Cropper
One more thing that needs to be changed is the following code required for requesting storage permissions
In OnActivityResult code
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, CropImage.PICK_IMAGE_PERMISSIONS_REQUEST_CODE);
thank you soo very much for valueable code..
i m a big fan of this site…
great job sir..
keep helping Android freshers like me with your simple and greate codes…
thank you soo much..
for marshmallow 6 and nougat 7, Use RunTime Permission for that it will work,
hi manish.
your code is working fine thank u so much.
can i fetch cropped image coordinates not image button coordinates.
when i do then only i fetch image button coordinate which is always same not result image coordinates.
plzz suggest me .thank u so much
Hi Manish,
Nice tutorial. By the way i would like to store the image in sharedpreferences so as when the application is closed,
the image again loads with the last set image.
Kindly help me with this.
I can not save multiple image in cache , By default this library save the cropped image in cache , but i can not save more than one.
How can we get the path of this cropped image? its urgent
Hi! i am new to android ,i have excuted the above code but when i reache the croping area i don’t see the crop button to enable croping so as to return to the main activity.plz help
hi
your code is working up to select an image and but status bar not showing and I don’t see any crop button.
what is the issue? do you know? do you want to check my code? please help me.
i think you disable the action bar, set the theme manually in manifest file.
My issues is crop image activity is not move after clicked the right button
Please help to over come its very urgent
Help guys, I am problem with the CropImage, once I select the imaga from the gallery or camera is crashes the app asnd there is no error in the logcat. Thanks.
Help guys, I have a problem with the CropImage, once I select the imaga from the gallery or camera is crashes the app asnd there is no error in the logcat. Thanks.