Application hangs when cropping image - android

I have the below crop method. When I call cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); my screen hangs at 'saving image'. If I don't call it, the cropped image is not written to file.
private void crop() {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(mImageCaptureUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 4);
cropIntent.putExtra("aspectY", 3);
cropIntent.putExtra("outputX", 500);
cropIntent.putExtra("outputY", 300);
File f = new File(Environment.getExternalStorageDirectory(),
"/temporary_holder.jpg");
try {
f.createNewFile();
} catch (IOException ex) {
Log.e("io", ex.getMessage());
}
uri = Uri.fromFile(f);
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
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 doesn't support the crop action!";
Toast toast = Toast
.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}

I have the same problem, it stucks with:
cropIntent.putExtra("outputX", 500);
.. so badly that the only way to repair this is to remove the batterie..
but if I take
cropIntent.putExtra("outputX", 200); it works fine..
(device HTC Sensation Z710e Android 4.0.3 (API 15))

Related

marshmallow : java.lang.illegalargumentexception: mediaFileUri must be a File Uri

I am having problem in marshmallow device while cropping a photo after capturing it through camera.
It is working fine on below 6 version devices.
here is my code:
if (requestCode == CAMERA_PICTURE) {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
// set data type to be sent , indicate image type and Uri of image
cropIntent.setDataAndType(mCapturedImageURI, "image/*");
List<ResolveInfo> list = getPackageManager().queryIntentActivities( cropIntent, 0 );
int size = list.size();
// handle the case if there's no cropper in the phone
if (size == 0) {
Toast.makeText(this, "Can not find image crop app", Toast.LENGTH_SHORT).show();
return;
} else {
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
//indicate output X and Y
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
String fileName = Ut.getDateTimeStamp();
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
mCropImageURI = getContentResolver()
.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values);
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT,
mCropImageURI);
//retrieve data on return
cropIntent.putExtra("return-data", true);
//start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, CROP_PICTURE);
return;
}
} else if (requestCode == CROP_PICTURE) {
getCameraPhotoFromIntent(data);
setImagePathToSource();
}
I have fixed by myself by removing
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT,
mCropImageURI);
as nexus 9 use Photos instead of gallery and "Photo" app not allowed Media URI .
So by removing this, I am able to crop the image.
Thank you.
Try this:
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.MARSHMALLOW) {
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCropImageURI);
}

Set default image cropper program in android

In my application the user selects an image. When the CROP_IMAGE intent is launched it displays the dialog to select one of the available image croppers installed on the device. I would like to solve that one of the installed programs launch default that user don't have to choose all time which program wants to use.
Is it possible to skip this chooser dialog and launch one image cropper automatically?
I found an answer :
Intent cropApps = new Intent("com.android.camera.action.CROP");
cropApps.setType("image/*");
List<ResolveInfo> list = this.getPackageManager().queryIntentActivities(cropApps, 0);
int size = list.size();
if (size == 0)
{
Toast.makeText(this, "Can not find image crop app", Toast.LENGTH_SHORT).show();
}
else
{
ResolveInfo res = list.get(0);
Intent cropIntent = new Intent();
cropIntent.setClassName(res.activityInfo.packageName, res.activityInfo.name);
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("outputX", 800);
cropIntent.putExtra("outputY", 800);
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("scale", true);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, PIC_CROP);
}

Crop a large Image with 2448*3264 Resolution

I tried below code to crop large image with pixel (2448*3264). But, This process is not working fine. Please correct the below code or give me another solution to achieve this images cropping process. Advance thanks to all.
private void performCrop(){
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(UrlGambar, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 2);
cropIntent.putExtra("aspectY", 3);
//cropIntent.putExtra("outputX", 256);
//cropIntent.putExtra("outputY", 256);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, PIC_CROP);
}
catch(ActivityNotFoundException anfe){
String errorMessage = "Whoops - your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
}
Intent com.android.camera.action.CROP is not a standard android intent and there are many devices that donot support this intent. Please refer to my answer in this post. I am using a library from github to do the cropping.

Intent setDataAndType as bitmap

I'm trying to use a method to crop a image. Exactly this method:
private void performCrop() {
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(**HERE**, "image/*");
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
//indicate output X and Y
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
//retrieve data on return
cropIntent.putExtra("return-data", true);
//start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, 1234);
}
catch(ActivityNotFoundException anfe){
Log.d("debugging","EXCEPTION");/*
//display an error message
String errorMessage = "Whoops - your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();*/
}
}
This line, asks for a Uri Data and String Type.
cropIntent.setDataAndType(**HERE**, "image/*");
But I just want to put this bitmap
Bitmap fotoCreada;
as Data, but I don't know how to do it.
Is there any way to achieve this?
Thanks.
EDIT
Okay, this is my code right now:
There's a button. When you click it:
public void onClick(View v) {
Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
if(isSDPresent) {
//Creem carpeta
File folder = new File(Environment.getExternalStorageDirectory().toString()+"/pic/");
folder.mkdirs();
//Recuperem data actual
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String currentDateandTime = sdf.format(new Date());
//Cridem a la camara.
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
resultingFile=new File(folder.toString() + "/"+currentDateandTime+".jpg");
Uri uriSavedImage=Uri.fromFile(resultingFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
//Començem activity
startActivityForResult(cameraIntent, 1888);
} else {
Toast toast = Toast.makeText(getActivity(), "Issues while accessing sdcard.", Toast.LENGTH_SHORT);
toast.show();
}
}
As you can see, it's calling startActivityForResult. Basically takes a picture, and I retrieve it on activityResult:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("debugging",""+resultCode);
if( requestCode == 1888 && resultCode == -1) { //-1 = TOT HA ANAT BE.
Bitmap photo = BitmapFactory.decodeFile(resultingFile.getPath());
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap photoRotated = Bitmap.createBitmap(photo, 0, 0, photo.getWidth(), photo.getHeight(), matrix, true);
this.fotoCreada=photoRotated;
((ImageView) myFragmentView.findViewById(R.id.fotoCapturada)).setImageBitmap(this.fotoCreada);
try {
FileOutputStream out = new FileOutputStream(this.resultingFile.getPath());
this.fotoCreada.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
performCrop();
}
if (requestCode == 1234 && resultCode == -1){
Bitmap bitmap = (Bitmap) data.getParcelableExtra("BitmapImage");
Log.d("debugging",""+bitmap.getHeight());
}
}
And as you can see from previous code, as I retrieve the bitmap, I call method performCrop. It's code, now, is:
private void performCrop() {
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(this.picUri, "image/*");
cropIntent.putExtra("BitmapImage", this.fotoCreada);
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
//indicate output X and Y
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
//retrieve data on return
cropIntent.putExtra("return-data", true);
//start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, 1234);
Log.d("debugging","he acabat performCrop");
}
catch(ActivityNotFoundException anfe){
Log.d("debugging","EXCEPTION");
//display an error message
String errorMessage = "Whoops - your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
But startActivityForResult from performCrop never ends up calling onActivityResult. Log cat says it just entered once, and should enter Twice. First one from the camera Activity and second from Crop activity.
-1
he acabat performCrop
Hope it's clear enough.
Thanks.
Bitmap implements Parcelable, so you could always pass it in the intent:
Intent intent = new Intent(this, NewActivity.class);
intent.putExtra("BitmapImage", bitmap);
and retrieve it on the other end:
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");
However, if the bitmap exists as a file or a resource, its is always better to pass the URI or ResourceID of the bitmap and not the bitmap itself. Passing the entire bitmap requires a lot of memory. Passing the URL requires very little memory and allows each activity to load and scale the bitmap as they need it.
Use Intent.putExtra. A bitmap is a parceable, so it will work. setDataAndType is used for URIs, but you aren't referencing a resource on the web or on disk.

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.

Categories

Resources