Taking pictures from camera or gallery is an essential feature for many applications those includes media in their apps. A simple notes app may need a profile picture to make the notes more personal. Getting a thumbnail image from camera is easy, but sometimes you want the full resolution image without storing it in gallery, crop it and avoid the possible memory exceptions.
In this tutorial we are going to learn building a simple social profile UI, choose the profile picture from camera or gallery with crop and image transformation features.
For cropping functionality, we are going to use uCrop library. This library is used many popular apps and tested on various devices / OS versions. Even though the library provides best cropping experience, it won’t provide an option to choose the input image from camera or gallery. All it takes is a bitmap and gives back the cropped bitmap.
In this article we use the same cropping library but on top of it, we’ll build a feature to pick the image from camera or gallery.
For information about uCrop, visit the official documentation.
Our goal is to build a simple social profile UI (like Instagram) and use the image cropping functionality to apply the profile image. You can take picture using camera or choose from gallery, crop and set it as profile image. So let’s start by creating a new project in Android Studio.
1. Create a new project in Android Studio from File ⇒ New Project and select Basic Activity from templates. I have given my package name as info.androidhive.imagepicker
2. Open app/build.gradle and add Dexter, ButterKnife, Glide, CircularImageView and uCrop dependencies.
3. Add the below resources to respective strings.xml, dimen.xml and colors.xml files.
4. Download this res folder and add the contents to your project’s res folder. This folder contains necessary icons needed to build the profile screen.
5. Open the layout file your main activity (activity_main.xml) and add the below code to achieve the profile layout.
Create a new xml layout layout_toolbar_profile.xml and add the below code.
Now if you run your project, you should able to see the screen as below.
Now as the UI part is done, let’s see how to add the image picking functionality on tapping the profile image or plus icon.
6. Create an xml file named file_paths.xml under res ⇒ xml folder. If you don’t see xml folder under res, create a new folder with the same name. Here we are defining a FileProvider path to store the camera images in a cached location instead of storing them in gallery.
7. Open AndroidManifest.xml and do the below changes.
> Add INTERNET, CAMERA and STORAGE permissions.
> Add UCropActivity intent to launch the crop activity.
> Add FileProvider information using the xml we have defined in the above step.
8. As we are using Glide to display the image, create a class named MyGlideModule and annotate the class with @GlideModule.
9. To reduce the complexity, I have written an activity that takes care of choosing the image and cropping. All you have to do is, add this activity to your project and call couple of lines to launch the activity. That’s all.
Create a blank activity ImagePickerActivity.java and add the below code.
To show the image picking choices, call ImagePickerActivity.showImagePickerOptions() method.
Once, an option is selected, you can pass Intent data depending on the choice. For example, to pick the image from gallery with 1×1 aspect ratio, the below intent can be used.
10. Now we’ll see how this can be applied to our profile activity. Open MainActivity.java and call image picker activity on tapping the profile image or plus icon.
Now run and test the app. You should be able to set the profile image from camera or gallery.
If you have any queries or suggestions, please do post in the comment section below.
Happy Coding 🙂
Hi there! I am Founder at androidhive and programming enthusiast. My skills includes Android, iOS, PHP, Ruby on Rails and lot more. If you have any idea that you would want me to develop? Let’s talk: [email protected]
awesome like always thanks…..what about android jetpack any plan for it??
I don’t planned yet.
Hi,
Can you put up a tutorial on EXO Player?
Thank you in advance
Good idea. Will write one.
Great article.
Thank You.
@Ravi Tamada:disqus Can u make a post about new DESIGN APP (material design 2.0) ? How use, make… ? Sorry for publish this question here
Could you explain a bit about your requirement? You mean the design or development?
Design sir
You can use Sketch or Adobe XD to design the layouts.
Here is one article on Sketchapp. Same applies to adobe XD also.
https://www.androidhive.info/2018/01/android-app-ui-designing-using-sketch-app-and-zeplin/
Thanks sir, how about development?
That you have to learn the Material components related info and the write the code manually.
nice tutorial
Thank You:)
Awesome as always 🙂
Thank you 🙂
hello sir, what/where is
activity_image_picker xml ??
It’s just a blank activity. You can get the code from here.
https://github.com/ravi8x/Android-Image-Picker-and-Cropping/blob/master/app/src/main/res/layout/activity_image_picker.xml
thank u sir its really really awesome as always tutorial and u helped me a lot while learning android. Thank you sir…
You are welcome Zaid 🙂
Thank you
but when I capture a photo from the camera I get this message :Unfortunately camera has stopped
Pls check the LogCat for the errors.
Could not find class ‘android.support.v4.view.ViewCompat$OnUnhandledKeyEventListenerWrapper’, referenced from method android.support.v4.view.ViewCompat.addOnUnhandledKeyEventListener
Could not find class ‘android.view.WindowInsets’, referenced from method android.support.v4.view.ViewCompat.dispatchApplyWindowInsets
Could not find class ‘android.view.WindowInsets’, referenced from method android.support.v4.view.ViewCompat.onApplyWindowInsets
Could not find class ‘android.view.View$OnUnhandledKeyEventListener’, referenced from method android.support.v4.view.ViewCompat.removeOnUnhandledKeyEventListener
Could not find class ‘android.support.v4.view.ViewCompat$1’, referenced from method android.support.v4.view.ViewCompat.setOnApplyWindowInsetsListener
Could not find class ‘android.graphics.drawable.RippleDrawable’, referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
Could not find class ‘android.app.AppOpsManager’, referenced from method android.support.v4.app.AppOpsManagerCompat.noteOp
Could not find class ‘android.app.AppOpsManager’, referenced from method android.support.v4.app.AppOpsManagerCompat.noteOpNoThrow
Could not find class ‘android.app.AppOpsManager’, referenced from method android.support.v4.app.AppOpsManagerCompat.noteProxyOp
Could not find class ‘android.app.AppOpsManager’, referenced from method android.support.v4.app.AppOpsManagerCompat.noteProxyOpNoThrow
Try File -> Invalidate Cache & Restart option from Android Studio. The APK might not be generated properly.
The error still exists but thank you
Okay.
I have this problem can you help me with this? I didn’t get the resource for GlideApp. I just copy the whole code as you said.
But when I download your code it worked properly.
Okay. Pls include this class in your project.
https://github.com/ravi8x/Android-Image-Picker-and-Cropping/blob/master/app/src/main/java/info/androidhive/imagepicker/MyGlideModule.java
problem solved by clean and rebuild the project. Thank You for your help and I MUST SAY your articles are great. I learned a lot from that.
Great. Here are the solutions you can try if you ever face this problem again.
1. Build -> Clean, Rebuild.
2. Build -> Clean, Make Project
3. Final step is to File -> Invalidate Cache & Restart.
hello, I’m having this problem too
I tried all these solutions
and nothing worked
what can I do ?
Hi Ravi:
I have this error: IOException: file:/data/user/0/com.ingeniapps.dicmax/cache/1552502359577.jpg (No such file or directory)
Help!
RAVI CHANGED MY LIFE I WENT FRON NULL TO DEVELOPPING REAL WORLD APPS BECAUSE OF YOU. SALUTE SIR
Thanks Holga 🙂
All the best!
sir some images from internal storage cant be selected using this library while some are selected it didnt even print logs to figure our error.
for example there is folder in my internal storage:
Internal StorageAmigoScreenLockFavorite
and other paths also from internal storage from where image cant be selected it show preview and all but after crop and selecting image it just getting nothing even logs cant be printed.. so plz help me i used this for real world app plz sir…..
Okay. It might be the issues with Crop library I am using. Could you check library issues tab on Github and see you can find anything related.
i couldn’t find any solution on github page of uCrop library sir…
I need to search and find the solution. Right now no idea 🙁
okay sir np whenever you find any solution plz let us know…. Thank you for kind support.
Sure.
After cropping the image when i click on the tick icon, my app crashes saying in log “File exists”
Really Nice Guide but, if I want to store the image in internal folder of app and then show it every time I reopen the app? Using internal storage and not cache. How much code I need to change (referred to this guide) to do this? Thanks!!
how to save image to Internal storage instead of cache?
Thank you very much , Ravi.!!!
Really nice,but i am facing the issue that, when i am selecting the image from gallery and setting on imageview,it’ working but when again i am selecting the same image from gallery, it’s not setting on imageview.
I see the problem. Have you called clearCache() function once the image is used? or may be before start the crop activity.
Yes i have done that.
i may be have same problem here. I can choose pic from gallery and set to profile imageview. but it gone when i press android button back, it will gone.. Do you know what is my problem
I have error on this 5 files..
this five is uneditable files.
i use androidx
Try like this
//Glide
implementation ‘com.github.bumptech.glide:glide:4.9.0’
implementation ‘com.github.bumptech.glide:annotations:4.9.0’
implementation(‘com.github.bumptech.glide:okhttp3-integration:4.0.0’) {
exclude group: ‘glide-parent’
}
annotationProcessor ‘com.github.bumptech.glide:compiler:4.9.0’
Sir its working great… kindly please tell me how to change the dimensions of box….in terms of length breadth so that we can have fixed dimensions image from user …its urgent help please!!
I’m getting this error at the time of project build. RequestOptions cannot be converted to GlideOptions.
Yes, it is really amazing post, new of uCrop library in image and we can do in image to pick the image from gallery with 1×1 aspect ratio as same.
Hi ! Great Post ! It help me a lot, but i’m facing an issue with the cropped image : When i choose an image from galery ans crop it, i successfully get it on the imageView, but when i choose the same picture and crop it again, it always display the previous cropped image , can i have some help ?
/**
*
The below line between Start and End is added to distinct if user select same image to crop than each time same image name replace with random number with .jpg to to
* overcome issue of same previously cropped image set. if you comment below line between Start and End than check for selecting same image with cropping different portion of image and result will be
* previously cropped image rather that current crop image. this is issue in Library
*/
/// Start
int random = new Random().nextInt();
String destURI = null;
if(destinationUri.toString().contains(“jpg”)) {
String str = random + “.jpg”;
destURI = destinationUri.toString().replace(“.jpg”, str);
}
else if(destinationUri.toString().contains(“png”)) {
String str = random + “.png”;
destURI = destinationUri.toString().replace(“.png”, str);
}
destinationUri = Uri.parse(destURI);
/// End
This also solves the problem where by the camera image selection works fine but pick from gallery doesn’t work. Worked fine for me. Thank you.
Hi! I am using your code thats working fine but when I am adding code for selecting the file from file manager that file could be of any type , the code is working in all version but when i run in Android pie it crashed , I could not understand where I am doing wrong, Please suggest the working code for this
Hey Ravi, this was a very good tutorial. Can you please share how to add different ASPECT RATIO options?
The different aspect ration are on the comments where he has set to 1 x 1
Thank you So Much..It was Wonderful tutorial..!
/data/user/0/com.anetossoftware.nasitparivar/cache/Screenshot_20191023-010431.png (No such file or directory) I want to upload this image to server. How can I do that
How to save in dataabase after take picture?
Thanks for the tutorial it works very well on my app. The thing is where can i get the image set by user. i want to send it to a server app via retrofit.
how to crop gallery image
Hello Sir,
Please create demo of compass with camera view.
Not image crop from gallery
Me too
Not getting bitmap from uri
Me too….
No crop from gallery… it exits
Hey, First of all thanks for the amazing tutorial.
How can this be modified to pick multiple Images from the gallery. can you please point me in the right direction?
I am getting File not found exception. Can you please help me why am i getting it.
image clear cache not working
it displays old images forever
Print some logs and see if there are errors while deleting them.
content.FileProvider error in manifest file
use this —> android:name=”androidx.core.content.FileProvider”
Hi there! Great tutorial! I have a question though, would you say that your tutorial respects the MVC pattern, if yes, can you explain to me how? I do’t think it does as I cannot see an actual controller…
Hello Mr Ravi , first of all thanks a million for your great tutorials, then I’ve got a small question , I’ll be thankful if you answer it, here it is : i wanted to compress the cropped image with zetbaitsu Compressor then upload it to my server , would you please help me with this ? just compress the cropped image using this library and for uploading i know you have another great tutorial and i will use that , Just Compressing part
thanks a lot Dear Ravi
form gallery use this given code not working…
AndroidHive
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = “//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.9”;
fjs.parentNode.insertBefore(js, fjs);
}(document, ‘script’, ‘facebook-jssdk’));
copyright © 2017 Droid5 Informatics Pvt Ltd
www.droid5.com