com.android.camera.action.CROP doesn't work at landscape mode - android

I have an issue: need to take photo with camera and then show screen with possibility to crop photo that is taken. I added suchfunction:
protected void callCropPhoto(Uri uri) {
try {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", avatar.getWidth());
intent.putExtra("aspectY", avatar.getHeight());
intent.putExtra("outputX", avatar.getWidth());
intent.putExtra("outputY", avatar.getHeight());
intent.putExtra("return-data", true);
startActivityForResult(intent, CROP_PHOTO_REQUEST_CODE);
} catch (Exception ex) {
// Some devices can't support image cropping.
}
}
When I get result from camera with photo I call this function with temporary uri to taken photo. When calls onActivityResult usualy I get RESULT_OK and data - all works good. But on one device (android version 2.3.4) in landscape mode I got RESULT_CANCELED and no screen with cropping appear. What is the problem?

Related

Want to make photo in Android, but it automatically downscales the photo to 160x160px

Hello fellow programmers. My problem: Every time I made a photo, Android automatically scales it down to 160x160px. I don't know why. Here is my code:
Here I set all the preferences for the camera:
public void ChosenPhoto(String extra) {
String gallery = "gallery";
String camera = "camera";
if (extra.equals(gallery)) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("return-data", true);
intent.putExtra("aspectX", 560);
intent.putExtra("aspectY", 560);
intent.putExtra("outputX", 560);
intent.putExtra("outputY", 560);
intent.putExtra("noFaceDetection", true);
intent.putExtra("screenOrientation", ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, PICK_FROM_GALLERY);
} else if (extra.equals(camera)) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString());
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 560);
intent.putExtra("aspectY", 560);
intent.putExtra("outputX", 560);
intent.putExtra("outputY", 560);
intent.putExtra("noFaceDetection", true);
intent.putExtra("screenOrientation", ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
intent.putExtra("return-data", true);
startActivityForResult(intent, PICK_FROM_CAMERA);
}
}
Here I use it later on:
Bundle extras = data.getExtras();
photoBit = extras.getParcelable("data");
ByteArrayOutputStream PhotoStream = new ByteArrayOutputStream();
photoBit.compress(Bitmap.CompressFormat.PNG, 100, PhotoStream);
photos = PhotoStream.toByteArray();
Log.e(TAG, "Width:" + photoBit.getWidth() );
ImageView.setImageBitmap(photoBit);
In the ImageView, I later see that it is scaled down. More precise: every time to 160x160px... I have no idea why.
Please help me. If you need more information, just ask for it.
What is returned in "data" is actually only a thumbnail and not the full-sized photo. It is not possible to get the full-sized image this way, but you need to create a file in which the camera will save it for you. Working example with explanation can be found from http://developer.android.com/training/camera/photobasics.html under title "Save the Full-size Photo".
First you need to create a new File that will store the image. You may want to make sure the file name does not collide with other files (append timestamp).
File file = new File(context.getExternalFilesDir( null ), "photo.jpg");
Then you specify this in the intent:
intent.putExtra( MediaStore.EXTRA_OUTPUT, Uri.fromFile( file ) );
activity.startActivityForResult( intent, REQUEST_TAKE_PHOTO );
In onActivityResult() you will check if photo was actually taken. You will use the File instance that you have created before that now has the image.
if ( ( requestCode == REQUEST_TAKE_PHOTO ) && ( resultCode == RESULT_OK ) ) {
If you want to put the image from the file into ImageView, you can do this:
Bitmap bmp = BitmapFactory.decodeFile( file.getAbsolutePath() );
imageView.setImageBitmap(bmp);

Android 4.3 crop gallery resultCode Cancel

My Galaxy Nexus is now running on Android 4.3 allowing me to test my application with this new version. Everything seems fine except cropping.
I have an application that uses the camera to take picture and then crop the image through the gallery app.
I am also able to choose a picture from the gallery and crop it after.
Since Android 4.3, the gallery application changed.
If i take a picture with the camera api and then ask the gallery to crop it in my onActivityResult method the resultCode is set to 0 (meaning cancel) whereas i clicked on "Save" from the crop view.
But if i choose a picture from the gallery and crop it everything works, the resultCode parameter is set to -1.
I call the same method to crop the picture in both cases.
I have quickpic (an alternative to the gallery app) on my phone, with it everything works !
private void performCrop(Uri picUri) {
try {
int aspectX = 750;
int aspectY = 1011;
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(picUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("scale", "true");
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
intent.putExtra("scaleUpIfNeeded", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCurrentPhotoPath)));
startActivityForResult(intent, CROP);
}
catch (ActivityNotFoundException anfe) {
String errorMessage = "Your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
Everything worked fine on Android 4.2.2.
Thank you for your help !
Have you considered just using a library like this one:
https://github.com/biokys/cropimage
I find the com.android.camera.action.CROP can sometimes behave differently from phone to phone and is not always available, so it could cause some problems for you anyway if you are looking to release it.
UPDATE:
I have tested the above library with Android 4.3 and it works with no problem. You just need to add the library to your project.
You can then write your method in a very similar way:
private void performCrop(Uri picUri) {
//you have to convert picUri to string and remove the "file://" to work as a path for this library
String path = picUri.toString().replaceAll("file://", "");
try {
int aspectX = 750;
int aspectY = 1011;
Intent intent = new Intent(this, CropImage.class);
//send the path to CropImage intent to get the photo you have just taken or selected from gallery
intent.putExtra(CropImage.IMAGE_PATH, path);
intent.putExtra(CropImage.SCALE, true);
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCurrentPhotoPath)));
startActivityForResult(intent, CROP);
}
catch (ActivityNotFoundException anfe) {
String errorMessage = "Your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
Above library is only useful if your cropping into a lot smaller images. If you want to crop to a better resolution images, it is best to use the Android Crop Intent.
picUri must be a valid URI which points to your image and outputUri should be a new file you created for writing the cropped image. It works on all devices and 4.3 Source code does indeed have com.android.camera.action.CROP intent available for usage. I've tested this on many devices and it works well.
private void performCrop(Uri picUri, Uri outputUri) {
try {
int aspectX = 2000;
int aspectY = 1200;
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(picUri, "image/*");
intent.putExtra("scale", "true");
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
intent.putExtra("scaleUpIfNeeded", true);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
startActivityForResult(intent, CROP);
}
catch (ActivityNotFoundException anfe) {
String errorMessage = "Your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
I've encountered this problem on a Nexus 10 as well. the crop intent returns a cancelled code. after some tweaking I've found a solution:
In my case the input file set in setDataAndType() was the same file as the output set using the MediaStore.EXTRA_OUTPUT extra. Using the same file for input and output worked fine on most devices, specifically on devices below 4.3. However on 4.3 it would result in canceled crops. Simply using different files for input and output resolved the issue.
So what you need to make sure of is that your picUri parameter points to a file that is not the same as your mCurrentPhotoPath. I'm not sure what exactly changed from 4.2 to 4.3 to cause this issue. But using different files seems to resolve it easily.

how can I save a file after cropping?

I am creating an android application. It takes a picture then allows you to crop it and then displays it. Problem is that it only saves the taken image not the cropped one. Basically i need it to save the cropped image. how can I save a file after cropping?
Code:
private void performCrop(){
//take care of exceptions
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(picUri, "image/*");
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1.5);
//indicate output X and Y
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
//retrieve data on return
cropIntent.putExtra("return", true);
//start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, PIC_CROP);
}
//respond to users whose devices do not support the crop action
catch(ActivityNotFoundException anfe){
//display an error message
String errorMessage = "Your device does not support cropping";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
Just add something like this:
try{
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
), fileName+".png"); //save to your pictures folder
outputFileURI = Uri.fromFile(file);
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileURI);
startActivityForResult(cropIntent, PIC_CROP);
} catch (IOException ioe){
// handle your exception
}
Remember to refresh the gallery after saving so that its instantly available in the gallery. So use this code maybe in your onActivityResult method?
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse
("file://" + Environment.getExternalStorageDirectory())));
Edit: Found a better way to refresh the gallery since sendBroadcast can be a inefficient if you are just refreshing for one image. Use a MediaScanner to scan the file like so
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(outputFileURI); // Add the path to the file
sendBroadcast(intent);
This will just scan for the new file and refresh that instead of the whole gallery.

Crop an image when selected from gallery in android

I want to crop an image in my application when it is selected from gallery.
i.e if I launch the gallery and select an image the cropping window should come like when we select an image from iPhone. Is it possible in Android.
I found one tutorial for cropping the image in android, but dont seem the way I wanted.
http://www.coderzheaven.com/2011/03/15/crop-an-image-in-android/
Yes it's possible to crop image in android by using com.android.camera.action.CROP. after picking image url from gallery.you will start Crop Editor as:
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setClassName("com.android.camera", "com.android.camera.CropImage");
File file = new File(filePath);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 96);
intent.putExtra("outputY", 96);
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, REQUEST_CROP_ICON);
When the picture select Activity return will be selected to save the contents.in onActivityResult:
Bundle extras = data.getExtras();
if(extras != null ) {
Bitmap photo = extras.getParcelable("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.JPEG, 75, stream);
// The stream to write to a file or directly using the photo
}
and see this post which is also help you for cropping image in android
This tutorial is exactly what you need enjoy:
Picking image from gallery:
Crop image after Intent pick action
Cheers
You can already tell the Camera/Gallery-Intent to start the crop-editor after the image is selected/taken:
Pick Image from Gallery:
Intent pickImageIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickImageIntent.setType("image/*");
pickImageIntent.putExtra("crop", "true");
pickImageIntent.putExtra("outputX", 200);
pickImageIntent.putExtra("outputY", 200);
pickImageIntent.putExtra("aspectX", 1);
pickImageIntent.putExtra("aspectY", 1);
pickImageIntent.putExtra("scale", true);
pickImageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriWhereToStore);
pickImageIntent.putExtra("outputFormat",
Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(pickImageIntent, RESULT_LOAD_IMAGE);
Take Photo:
Intent takePicIntent = new Intent("android.media.action.IMAGE_CAPTURE");
takePicIntent .putExtra("crop", "true");
takePicIntent .putExtra("outputX", 200);
takePicIntent .putExtra("outputY", 200);
takePicIntent .putExtra("aspectX", 1);
takePicIntent .putExtra("aspectY", 1);
takePicIntent .putExtra("scale", true);
takePicIntent .putExtra(MediaStore.EXTRA_OUTPUT, uriWhereToStore);
takePicIntent .putExtra("outputFormat",
Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(takePicIntent , RESULT_LOAD_IMAGE);
Although part of the internal API, the com.android.camera.action.CROP seems like it is well-supported on most Android devices. This might get you started:
final Intent intent = new Intent("com.android.camera.action.CROP");
intent.setData(uriOfImageToCrop);
intent.putExtra("outputX", 400);
intent.putExtra("outputY", 400);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("noFaceDetection", true);
intent.putExtra("output", Uri.fromFile(someOutputFile));
startActivityForResult(intent, SOME_RANDOM_REQUEST_CODE);
Then handle what you need to do in the onActivityResult() method of your Activity. Your output file should be the cropped image.
Since this Intent action is part of the internal API, however, I would strongly advise that you have some sort of fallback behavior if some device does not support the Intent. Some manufacturers provide their own Gallery apps and so there is no way of knowing whether or not the user's device will recognize the Intent. PLEASE DON'T FORGET THIS!! :)
I solved this problem this way
private void pickUserImage() {
if (doHavePermission()) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("crop", "true");
photoPickerIntent.putExtra("scale", true);
photoPickerIntent.putExtra("outputX", 256);
photoPickerIntent.putExtra("outputY", 256);
photoPickerIntent.putExtra("aspectX", 1);
photoPickerIntent.putExtra("aspectY", 1);
photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
startActivityForResult(photoPickerIntent, PICK_FROM_GALLERY);
}
}
find my complete solution here in stackoverflow post
Nobody will tell you which extra is needed unless you try it:
val intent = Intent(Intent.ACTION_PICK)
intent.apply {
type = "image/*"
putExtra("crop", "true") // NOTE: should be string
putExtra("outputX", 300) // This is needed, editor can't close without these two
putExtra("outputY", 300) // This is needed
putExtra("scale", true)
putExtra("aspectX", 1)
putExtra("aspectY", 1)
putExtra("return-data", true)
}
startActivityForResult(intent, YOUR_INT_CODE)

Fail Image cropping in Android

so I want to choose an image from gallery and then crop it:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), PHOTO_PICKED_WITH_DATA);
OK, pick the photo and then catch it onActivityResult, then crop it:
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(mAvatarUri, "image/*");
intent.putExtra("crop", true);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", ICON_SIZE);
intent.putExtra("outputY", ICON_SIZE);
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mAvatarUri);
intent.putExtra("return-data", true);
startActivityForResult(intent, CROP_IMAGE);
now, the problem is when i want to transform it into bytes and then send it inside an xml... it doesn't take only the cropped image but instead the whole image itself...
also, i cannot access cropped image uri, it says file not found!
hmmmm, seems like my cropped image weren't saved after all...
how can i suppose to fix this?
Samsung ACE 2.3.4
Check this code in the following link.
Crop Image
It works fine for me..
I don't know how you got that technique to crop image. But, for me, I always use this library. And it never failed to impress me. Work from android 2.1 all the way to 3.2 (never test it on 4.0 onward).
Here's how I do it:
Intent cropIntent = new Intent(imageProcessActivity,
CropImage.class);
cropIntent.putExtra("image-path",
FileUtil.saveTempFile(ImageProcessActivity.processedBitmap, filename));
cropIntent.putExtra("scale", true);
imageProcessActivity.startActivityForResult(cropIntent, ImageProcessActivity.INTENT_CROP_CODE);
and here's how to catch the result:
if (requestCode == INTENT_CROP_CODE && resultCode == RESULT_OK) {
Bundle extras = intent.getExtras();
if (extras != null) {
Uri uri = null;
uri = (Uri) extras.get("imageCrop");
Bitmap bitmap = null;
try {
bitmap = ImageUtil.decodeFile(
new File(new URI(uri.toString())),
AppConstant.MAX_IMAGE_SIZE);
} catch (URISyntaxException e) {
e.printStackTrace();
}
processedBitmap = bitmap;
selectedImage.setImageBitmap(bitmap);
}
}

Categories

Resources