I'm trying to capture an image from the Android Camera/ Pick an image from the gallery and then crop it before performing other operations on it. I'm having trouble with getting back the URI of the cropped image. Any help on how to get back the URI of the image once it has been cropped would be much appreciated!
The code below pertains to my onActivityResult and my function performing the crop
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_FILE || requestCode == REQUEST_IMAGE_CAPTURE) {
if(!IS_CAMERA_USED) {
selectedImageUri = data.getData();
}
performCrop();
}
else if(requestCode == CROP_IMAGE){
selectedImageUri = data.getData();
onSelectedImageResult();
}
}
}
public void performCrop() {
// take care of exceptions
Display display = getWindowManager().getDefaultDisplay();
try {
// call the standard crop action intent (the user device may not
// support it)
Intent cropIntent = new Intent("com.android.camera.action.CROP");
// indicate image type and Uri
cropIntent.setDataAndType(selectedImageUri, "image/*");
// set crop properties
cropIntent.putExtra("crop", "true");
// indicate aspect of desired crop
cropIntent.putExtra("aspectY", 1);
if(IS_PROFILE_PICTURE) {
cropIntent.putExtra("aspectX", 1);
}
else {
cropIntent.putExtra("aspectX", 2);
}
// indicate output X and Y
cropIntent.putExtra("outputX", display.getWidth());
cropIntent.putExtra("outputY", display.getHeight());
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, CROP_IMAGE);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe) {
Toast toast = Toast
.makeText(this, "This device doesn't support the crop action!", Toast.LENGTH_SHORT);
toast.show();
}
}
The problem is in the line selectedImageUri = data.getData(), where data.getData() returns null after having done the crop. How do I get back the URI of the cropped image? I don't want to get data.getExtras.getParcelable("data") as that returns the thumbnail and ruins the image resolution.
Thanks in advance!
You can get the image bitmap with this code:
if (requestCode == CROP_IMAGE) {
if (data != null) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap selectedBitmap = extras.getParcelable("data");
//imgView.setImageBitmap(selectedBitmap);
}
}
}
URI is not possible I think, because the cropped image is not saved on the storage.
Thanks for all your answers, but I found something way simpler to incorporate and use that avoids all hassles due to the `com.android.camera.action.CROP' class, and it can be found here
I think that you should save the cropped Bitmap to your storage, and then use the URI of the cropped Bitmap to performe something over it!
I know it's not a professional work but at least it should do it
Related
I have a problem regarding cropping image in android studio, whenever I run this cropping code on my device or any other One-plus device, it runs efficiently. But other devices like Redmi, Samsung, Motorola, crash after reaching this cropping part. if I comment out the function call to the cropping function, it runs smoothly on all devices but at cost of non-availability of cropping
public void ImageCropFunction(Uri uri) {
// Image Crop Code
try {
Intent CropIntent = new Intent("com.android.camera.action.CROP");
Toast.makeText(getContext(),"plz, Crop the Required part",Toast.LENGTH_LONG).show();
CropIntent.setDataAndType(uri, "image/*");
CropIntent.putExtra("crop", "true");
CropIntent.putExtra("outputX", 1024);
CropIntent.putExtra("outputY", 1024);
CropIntent.putExtra("return-data", true);
CropIntent.putExtra("return-uri", uri.toString());
startActivityForResult(CropIntent, 222);
}catch (ActivityNotFoundException e) {
}
}
What to use
You can use uCrop library.
Implemention
Make sure you have this line in your settings.gradle
maven { url "https://jitpack.io" }
Add it to your build.gradle.
implementation 'com.github.yalantis:ucrop:2.2.6'
Then you should add it to your manifest
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"/>
How to use
You can crop a image like this
UCrop.of(yourImageUri, whereToSaveYourCroppedImageUri)
.withAspectRatio(16, 9) // you can change the aspect ratio.
.withMaxResultSize(maxWidth, maxHeight) // you can add a custom result height for the image. eg 512 X 512
.start(context); // enter the context and the crop will start.
Get the result
You can fetch the result in the onActivityResult like this
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == UCrop.REQUEST_CROP) {
final Uri resultUri = UCrop.getOutput(data);
// crop is successful
} else if (resultCode == UCrop.RESULT_ERROR) {
final Throwable cropError = UCrop.getError(data);
// crop failed
}
}
Output
View the output gif from here
Android does not have a CROP Intent. There is no requirement for any device to support that undocumented Intent, let alone with those undocumented extras. There are dozens of libraries for image cropping. Please use one.
I have some troubles to display images in OpenGL.
Actually I'm able to display images from gallery in opengl. The problem occurs when I try to show one from the camera.
For me, OpenGL have to display the image from the camera as it does with the gallery ones. Obviously I'm making something wrong.
Any help will be appreciated.
Intent from gallery:
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/");
startActivityForResult(intent, 2);
Intent from camera:
Intent takePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePic.resolveActivity(getPackageManager()) != null) {
File imagen = controler.createPhotoFile(getExternalFilesDir(Environment.DIRECTORY_PICTURES));
if (imagen != null) {
photoUri = FileProvider.getUriForFile(this, "my.fileprovider", imagen);
takePic.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(takePic, 1);
}
}
This is my onActivityResult where I send the URI to a method which convert it to a bitmap and send it.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case 1:
sendImagenPanel(photoUri);
break;
case 2:
sendImagenPanel(data.getData());
break;
}
}
}
private void sendImagenPanel(Uri uri) {
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
final Bitmap imagen = controler.getCroppedBitmap(controler.scaledBitmap(bitmap, 256));
final CasillaOG casilla = ((GLSurfacePanel) gLViewPanel).getRendererPanel().getCuboSelected();
gLViewPanel.queueEvent(new Runnable() {
#Override
public void run() {
casilla.loadNewTexture(imagen);
casilla.setImagen(imagen);
}
});
gLViewPanel.requestRender();
}
In case someone is interested. I realize that the problem is not on the method that calls OpenGL. If I run the same code on the onActivityResult works from the gallery requestCode but not on the camera one, in my Samsung Galaxy Tab A. Why I mention my device? because if I run the app on a Huawei P9 lite, the gallery images are not display either. In both cases appears the next problem on the console:
call to opengl es api with no current context (logged once per thread)
After search that problem, I suppose that the intents of the camera and gallery use OpenGL and its originate a conflict with my own OpenGL environment.
Finally, I opted to set a bitmap field and add the texture in on the onDrawFrame. Obviously, with a boolean to make it one time.
I want the user to be able to access their gallery (by clicking the add photo ImageView), upload a photo of their choosing, and display that photo in the circular profile photo spot. I can't seem to find any definitive guides on how to do this. What is the easiest/best way to go about it? (in Java).
(I would have commented, but I canĀ“t, since I do not have 50 rep.)
You might wanna check:
Get Image from the Gallery and Show in ImageView
(Keep in mind that this is only about loading the Image, saving would need some extra)
Cheers!
you can use this to pick your photo:
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, RESULT_LOAD_IMG);
and below code is your on activity result:
#Override
protected void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
if (resultCode == RESULT_OK) {
try {
final Uri imageUri = data.getData();
final InputStream imageStream = getContentResolver().openInputStream(imageUri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
image_view.setImageBitmap(selectedImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(PostImage.this, "Something went wrong", Toast.LENGTH_LONG).show();
}
}else {
Toast.makeText(PostImage.this, "You haven't picked Image",Toast.LENGTH_LONG).show();
}
}
Everything works fine except image updation! When I register a new user and when I click in the image, it opens my image gallery, I choose any image, and it back to register activity but it won't update. Also I'm unable to register because that image is not uploading successfully and we sat if imagepath == null, show that's why toast error is coming that fill all the details.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == PICK_IMAGE && requestCode == RESULT_OK && data.getData() !=null){
imagePath = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imagePath);
userProfilePic.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
NOTE:
I tried multiple images, same issue.
There is no error in logcat.
Default image is showing perfectly when we first time try to register that time we sat android logo which is a default.
I can't register without selecting any image because image path == null.
No problem of image size.
Guys, any solution?
so this was working lovely till yesterday when I upgraded my phone to 5.0.0 and tested the application out in a 5.0.0 emulator. Basically the purpose is to allow the user to take a photo, return it, open it to allow cropping then return it and set it as an imageview.
Everything worked fine before but now the intent in onActivityResult is null.
Here's code:
public void takeDisplayPicture(View view) {
final String TAKE_DISPLAY_PICTURE = "Take Display Picture";
Log.d(TAKE_DISPLAY_PICTURE, "Clicked");
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA_CAPTURE);
} catch (ActivityNotFoundException e) {
String msg = "Your device doesn't support a camera!";
Toast toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
toast.show();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final String RETURN_DISPLAY_PICTURE = "Return Display Picture";
Log.d(RETURN_DISPLAY_PICTURE, "Returned");
if (resultCode == RESULT_OK && requestCode == CAMERA_CAPTURE) {
picUri = data.getData();
performCrop(picUri);
} else if (requestCode == PIC_CROP) {
Bundle extras = data.getExtras();
bitmap = extras.getParcelable("data");
displayPicture.setImageBitmap(bitmap);
}
}
private void performCrop(Uri picUri) {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, PIC_CROP);
} catch (ActivityNotFoundException e) {
String msg = "Your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
toast.show();
}
}
First, Android does not have a CROP Intent.
With respect to the null Uri, it is supposed to be null. Quoting the ACTION_IMAGE_CAPTURE documentation:
The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field.
You do not have EXTRA_OUTPUT, and so you are supposed to get your image via the poorly-documented (Bitmap)data.getExtras().get("data");.