Android Full Image From Crop Intent - android

I am taking images using the camera on an Android phone. After the image is taken, I pass the full image as a uri to the crop intent (com.android.camera.action.CROP). However, when the crop intent comes back, it returns in the parcelable at thumbnail size. I have tried to save the image from the camera in a file and send the uri of the file instead but it doesn't open the image in the crop intent. How can I get the full size image that I cropped in the crop intent from the parcel it sends back? Here is some of the code I am using:
public void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (resultCode != Activity.RESULT_CANCELED) {
Uri uri = null;
switch (requestCode) {
case FILE_SELECT_CODE:
if (intent.getData() != null) {
uri = intent.getData();
cropSelectedPicture(uri);
}
break;
case PICTURE_SELECT_CODE:
uri = intent.getData();
if (uri == null) {
Bundle bundle = intent.getExtras();
Bitmap photo = null;
if (bundle != null) {
photo = bundle.getParcelable("data");
}
finishChangeProfilePicture(photo);
} else {
cropSelectedPicture(uri);
}
break;
case FILE_CROP_CODE:
Bundle extras = intent.getExtras();
Bitmap thePic = extras.getParcelable("data");
uri = extras.getParcelable("uri");
finishChangeProfilePicture(thePic);
break;
}
}
super.onActivityResult(requestCode, resultCode, intent);
}
public void showCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra("crop", "true");
intent.putExtra("outputX", pictureWidth);
intent.putExtra("outputY", pictureHeight);
intent.putExtra("aspectX", pictureWidth);
intent.putExtra("aspectY", pictureHeight);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
try {
cordova.startActivityForResult(
this, Intent.createChooser(intent, "Take Picture"),
PICTURE_SELECT_CODE);
} catch (android.content.ActivityNotFoundException ex) {
// Potentially direct the user to the Market with a Dialog
Toast.makeText(context, "Please install a Camera application.",
Toast.LENGTH_SHORT).show();
}
}
public void cropSelectedPicture(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("outputX", pictureWidth);
intent.putExtra("outputY", pictureHeight);
intent.putExtra("aspectX", pictureWidth);
intent.putExtra("aspectY", pictureHeight);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
PackageManager packageManager = context.getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
if (activities.size() > 0) {
for (int i = 0; i < activities.size(); i++) {
String label = (String) activities.get(i).loadLabel(packageManager);
if (label.equals("Crop picture")) {
ActivityInfo activity = activities.get(i).activityInfo;
ComponentName name = new ComponentName (activity.applicationInfo.packageName,
activity.name);
intent.setComponent(name);
}
}
}
try {
cordova.startActivityForResult(this, intent, FILE_CROP_CODE);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(context, "Please install a Cropping program", Toast.LENGTH_SHORT).show();
}
}

Okay, so what I had to do was save the uri from the camera intent and then save the image to that intent when coming out of the crop intent. I had tried this once before but it was to an internal file to the app instead of to the content resolver. (Fair warning: This is a cordova project, not a native android project, so if you are having trouble with the Media.getBitmap line, then remove the cordova.getActivity() part and that should make it work) Here is what I changed:
public void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (resultCode != Activity.RESULT_CANCELED) {
switch (requestCode) {
case FILE_SELECT_CODE:
if (intent.getData() != null) {
uri = intent.getData();
cropSelectedPicture();
}
break;
case PICTURE_SELECT_CODE:
uri = intent.getData();
if (uri == null) {
Bundle bundle = intent.getExtras();
Bitmap photo = null;
if (bundle != null) {
photo = bundle.getParcelable("data");
}
finishChangeProfilePicture(photo);
} else {
cropSelectedPicture();
}
break;
case FILE_CROP_CODE:
Bitmap theUriPic;
try {
theUriPic = Media.getBitmap(cordova.getActivity().getContentResolver(), uri);
finishChangeProfilePicture(theUriPic);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
super.onActivityResult(requestCode, resultCode, intent);
}
public void cropSelectedPicture() {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("outputX", pictureWidth);
intent.putExtra("outputY", pictureHeight);
intent.putExtra("aspectX", pictureWidth);
intent.putExtra("aspectY", pictureHeight);
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.putExtra("return-data", true);
PackageManager packageManager = context.getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
if (activities.size() > 0) {
for (int i = 0; i < activities.size(); i++) {
String label = (String) activities.get(i).loadLabel(packageManager);
if (label.equals("Crop picture")) {
ActivityInfo activity = activities.get(i).activityInfo;
ComponentName name = new ComponentName (activity.applicationInfo.packageName,
activity.name);
intent.setComponent(name);
}
}
}
try {
cordova.startActivityForResult(this, intent, FILE_CROP_CODE);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(context, "Please install a Cropping program", Toast.LENGTH_SHORT).show();
}
}

Related

Editing is not supported for this Image Cropping an Image

I have a picture I want to post as imageButton but before posting it I have a cropper:
private void CropImage() {
try {
CropIntent = new Intent("com.android.camera.action.CROP");
CropIntent.setDataAndType(uri, "image/*");
CropIntent.putExtra("crop", "true");
CropIntent.putExtra("outputX", 180);
CropIntent.putExtra("outputY", 180);
CropIntent.putExtra("aspectX", 3);
CropIntent.putExtra("aspectY", 4);
CropIntent.putExtra("scaleUpIfNeeded", true);
CropIntent.putExtra("return-data", true);
startActivityForResult(CropIntent , 1);
}
catch (ActivityNotFoundException ex){
}
}
And when I select a picture from gallery or take a picture with my camera it shows a toast Editing is not supported for this Image, and I'm not sure what's really causing this.
This is my GalleryOpen() and CameraOpen():
private void GalleryOpen() {
GalleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(Intent.createChooser(GalleryIntent, "Select Images From Gallery"), 2);
}
private void CameraOpen() {
CamIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
file = new File(Environment.getExternalStorageDirectory(),
"file"+String.valueOf(System.currentTimeMillis())+ ".jpg");
uri = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".provider", file);
CamIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
CamIntent.putExtra("return-data", true);
CamIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(CamIntent, 0);
}
And my OnActivityResult:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0 && resultCode == RESULT_OK)
CropImage();
else if(requestCode == 2) {
if (data != null) {
uri = data.getData();
CropImage();
}
}
else if(requestCode == 1) {
if(data != null){
Bundle bundle = data.getExtras();
Bitmap bitmap = bundle.getParcelable("data");
imageHolder.setImageBitmap(bitmap);
}
}
}

crop issue in android : Image aspect ratio is not maintained [duplicate]

I am having a hard time in figuring out how to let the user crop the picture.
I would like to give bitmap variable with loaded bitmap to crop the picture before setting it as wallpaper. But I'm failing to do so... Here is that i tried.
First version. = Works as expected BUT the returned image is in poor resolution. Changing the output to higher value doesn't help. As I saw in some post it is not recommended to use camera as not all devices support this.
Intent intent = new Intent("com.android.camera.action.CROP");
String path = Images.Media.insertImage(context.getContentResolver(), loaded,null, null);
Uri uri = Uri.parse(path);
intent.setData(uri);
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 300);
intent.putExtra("outputY", 300);
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, 2);
Second. Load up image chooser, and crop afterwards. How can I configurate this to load crop directly on my image? Just like in version 1
Intent photoPickerIntent = new Intent(MediaStore.ACTION_PICK);
photoPickerIntent.setData(uri);
photoPickerIntent.putExtra("crop", "true");
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(photoPickerIntent, 2);
And onActivity result
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) { return; }
if(requestCode == 2) {
Bundle extras = data.getExtras();
if(extras != null ) {
Bitmap photo = extras.getParcelable("data");
loaded = photo;
}
WallpaperManager myWallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
myWallpaperManager.setBitmap(loaded);
} catch (IOException e) {}
}
}
I do not know whever these are the correct methods to make this done, but I hope somebody could point me in the right direction. Which, why, and how to use.
Update: I am still waiting for someone to point out how to do it correctly, answers below are working but returning images in poor resolution, so they are not an option to use
Ok Dear Here I put my Whole code of Crop Image In Android.
This the Global variable.
//This For Image Crop
/**
* Uri for set image crop option .
*/
private Uri mImageCaptureUri;
/**
* int for set key and get key from result activity .
*/
public final int CROP_FROM_CAMERA = 0;
/**
* Bitmap for apply Crop Operation Result.
*/
private Bitmap _tempOpration;
//This is Crop Method.
/**
* Method for apply Crop .
* #param filePath - String path of file .
*/
private void doCrop(String filePath){
try{
//New Flow
mImageCaptureUri = Uri.fromFile(new File(filePath));
final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getPackageManager().queryIntentActivities( intent, 0 );
int size = list.size();
if (size == 0)
{
Toast.makeText(this, "Can not find image crop app", Toast.LENGTH_SHORT).show();
return;
}
else
{
intent.setData(mImageCaptureUri);
intent.putExtra("outputX", 300);
intent.putExtra("outputY", 300);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
if (size == 1)
{
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, CROP_FROM_CAMERA);
}
else
{
for (ResolveInfo res : list)
{
final CropOption co = new CropOption();
co.title = getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
co.icon = getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
co.appIntent= new Intent(intent);
co.appIntent.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
cropOptions.add(co);
}
CropOptionAdapter adapter = new CropOptionAdapter(getApplicationContext(), cropOptions);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose Crop App");
builder.setAdapter( adapter, new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int item )
{
startActivityForResult( cropOptions.get(item).appIntent, CROP_FROM_CAMERA);
}
});
builder.setOnCancelListener( new DialogInterface.OnCancelListener()
{
public void onCancel( DialogInterface dialog )
{
if (mImageCaptureUri != null )
{
getContentResolver().delete(mImageCaptureUri, null, null );
mImageCaptureUri = null;
}
}
} );
AlertDialog alert = builder.create();
alert.show();
}
}
}
catch (Exception ex)
{
genHelper.showErrorLog("Error in Crop Function-->"+ex.toString());
}
}
This is the another Class witch use for find Crop Activity Intent in Application.
CropOption Class.
public class CropOption
{
public CharSequence title;
public Drawable icon;
public Intent appIntent;
}
this is use For Display List.
CropOptionAdapter
public class CropOptionAdapter extends ArrayAdapter<CropOption>
{
private ArrayList<CropOption> mOptions;
private LayoutInflater mInflater;
public CropOptionAdapter(Context context, ArrayList<CropOption> options)
{
super(context, R.layout.crop_selector, options);
mOptions = options;
mInflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup group)
{
if (convertView == null)
convertView = mInflater.inflate(R.layout.crop_selector, null);
CropOption item = mOptions.get(position);
if (item != null) {
((ImageView) convertView.findViewById(R.id.iv_icon)).setImageDrawable(item.icon);
((TextView) convertView.findViewById(R.id.tv_name)).setText(item.title);
return convertView;
}
return null;
}
}
Layout File For CropOptionAdapter
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:gravity="center_vertical">
<ImageView
android:id="#+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""/>
</LinearLayout>
This is the resultActivity.witch give the crop image.
/**
* #see android.app.Activity#onActivityResult(int, int, android.content.Intent)
*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) return;
switch (requestCode)
{
case CROP_FROM_CAMERA:
if (data == null)
{
genHelper.showToast("No Crop Activity in This");
return;
}
final Bundle extras = data.getExtras();
if (extras != null)
{
try
{
_tempOpration=extras.getParcelable("data");
imageLayout.setImageBitmap(_tempOpration);
_tempOpration=null;
}
catch (Exception e)
{
e.printStackTrace();
}
}
break;
}
}
//Do This Type It's work on my live app.
genHelper.showToast("No Crop Activity in This");
is my general Class to help display toast message and Error Log.
Bestof Luck.
First, variables:
final int PIC_CROP = 2;
Uri imageUri;
Bitmap thePic;
Before you take a pic from your Camera or your Gallery, put your image into a Uri (imageUri) , use a method called here as "performCrop()" inside try/catch:
private void performCrop(){
try {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getPackageManager().queryIntentActivities( intent, 0 );
int size = list.size();
if (size >= 0) {
intent.setData(imageUri);
intent.putExtra("crop", "false");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 256);
intent.putExtra("outputY", 256);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, 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();
}
}
On method onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if(requestCode == PIC_CROP){
if (resultCode == RESULT_OK) {
Bundle extras = intent.getExtras();
thePic = extras.getParcelable("data");
imageViewPhoto.setImageBitmap(thePic); //in my case, set the image on screen
}else{
//do something
}
}
}
As mentioned in similar threads, Android does not have an official crop intent
(https://commonsware.com/blog/2013/01/23/no-android-does-not-have-crop-intent.html), so I would stay away from using "com.android.camera.action.CROP".
However, in the time since this question was originally posted, Android has added a new API in Kitkat (level 19) that allows users to summon a crop-this-image-and-set-as-wallpaper Activity. See WallpaperManager.getCropAndSetWallpaperIntent(), and this might address your original question.
I also had the problem using the camera and ACTION_PICK that the returned image was very small despite the passed resolution being much larger. I got around this storing the resulted crop image in a temporary file
// temporary storage location, preferably in your cache directory
private final String tempFilePath = "somePath";
// URI instantiated with your temporary storage location
private Uri tempuri = Uri.fromFile(new File(tempFilePath));
// code for startActivityForResult
private final static int ACTIVITY_CROP_IMAGE = 1;
and calling the intent like this
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("crop", "true");
photoPickerIntent.putExtra("aspectX", wallpaperWidth);
photoPickerIntent.putExtra("aspectY", wallpaperHeight);
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempuri);
photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(photoPickerIntent, ACTIVITY_CROP_IMAGE);
and then in onActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode != RESULT_OK)
return;
if(requestCode == ACTIVITY_CROP_IMAGE)
{
try
{
Bitmap bmp = BitmapFactory.decodeFile(tempFilePath);
if(bmp != null)
{
WallpaperManager myWallpaperManager = WallpaperManager.getInstance(getApplicationContext());
myWallpaperManager.setBitmap(bmp);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if(tempFilePath != null)
{
File tempFile = new File(tempFilePath);
if(tempFile.exists())
{
tempFile.delete();
}
}
}
}
}
I constructed the above code from the top of my head and didn't actually compile any of it. But the basics are correct and you should get the hang ;-)

Let user crop image

I am having a hard time in figuring out how to let the user crop the picture.
I would like to give bitmap variable with loaded bitmap to crop the picture before setting it as wallpaper. But I'm failing to do so... Here is that i tried.
First version. = Works as expected BUT the returned image is in poor resolution. Changing the output to higher value doesn't help. As I saw in some post it is not recommended to use camera as not all devices support this.
Intent intent = new Intent("com.android.camera.action.CROP");
String path = Images.Media.insertImage(context.getContentResolver(), loaded,null, null);
Uri uri = Uri.parse(path);
intent.setData(uri);
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 300);
intent.putExtra("outputY", 300);
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, 2);
Second. Load up image chooser, and crop afterwards. How can I configurate this to load crop directly on my image? Just like in version 1
Intent photoPickerIntent = new Intent(MediaStore.ACTION_PICK);
photoPickerIntent.setData(uri);
photoPickerIntent.putExtra("crop", "true");
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(photoPickerIntent, 2);
And onActivity result
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) { return; }
if(requestCode == 2) {
Bundle extras = data.getExtras();
if(extras != null ) {
Bitmap photo = extras.getParcelable("data");
loaded = photo;
}
WallpaperManager myWallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
myWallpaperManager.setBitmap(loaded);
} catch (IOException e) {}
}
}
I do not know whever these are the correct methods to make this done, but I hope somebody could point me in the right direction. Which, why, and how to use.
Update: I am still waiting for someone to point out how to do it correctly, answers below are working but returning images in poor resolution, so they are not an option to use
Ok Dear Here I put my Whole code of Crop Image In Android.
This the Global variable.
//This For Image Crop
/**
* Uri for set image crop option .
*/
private Uri mImageCaptureUri;
/**
* int for set key and get key from result activity .
*/
public final int CROP_FROM_CAMERA = 0;
/**
* Bitmap for apply Crop Operation Result.
*/
private Bitmap _tempOpration;
//This is Crop Method.
/**
* Method for apply Crop .
* #param filePath - String path of file .
*/
private void doCrop(String filePath){
try{
//New Flow
mImageCaptureUri = Uri.fromFile(new File(filePath));
final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getPackageManager().queryIntentActivities( intent, 0 );
int size = list.size();
if (size == 0)
{
Toast.makeText(this, "Can not find image crop app", Toast.LENGTH_SHORT).show();
return;
}
else
{
intent.setData(mImageCaptureUri);
intent.putExtra("outputX", 300);
intent.putExtra("outputY", 300);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
if (size == 1)
{
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, CROP_FROM_CAMERA);
}
else
{
for (ResolveInfo res : list)
{
final CropOption co = new CropOption();
co.title = getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
co.icon = getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
co.appIntent= new Intent(intent);
co.appIntent.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
cropOptions.add(co);
}
CropOptionAdapter adapter = new CropOptionAdapter(getApplicationContext(), cropOptions);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose Crop App");
builder.setAdapter( adapter, new DialogInterface.OnClickListener()
{
public void onClick( DialogInterface dialog, int item )
{
startActivityForResult( cropOptions.get(item).appIntent, CROP_FROM_CAMERA);
}
});
builder.setOnCancelListener( new DialogInterface.OnCancelListener()
{
public void onCancel( DialogInterface dialog )
{
if (mImageCaptureUri != null )
{
getContentResolver().delete(mImageCaptureUri, null, null );
mImageCaptureUri = null;
}
}
} );
AlertDialog alert = builder.create();
alert.show();
}
}
}
catch (Exception ex)
{
genHelper.showErrorLog("Error in Crop Function-->"+ex.toString());
}
}
This is the another Class witch use for find Crop Activity Intent in Application.
CropOption Class.
public class CropOption
{
public CharSequence title;
public Drawable icon;
public Intent appIntent;
}
this is use For Display List.
CropOptionAdapter
public class CropOptionAdapter extends ArrayAdapter<CropOption>
{
private ArrayList<CropOption> mOptions;
private LayoutInflater mInflater;
public CropOptionAdapter(Context context, ArrayList<CropOption> options)
{
super(context, R.layout.crop_selector, options);
mOptions = options;
mInflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup group)
{
if (convertView == null)
convertView = mInflater.inflate(R.layout.crop_selector, null);
CropOption item = mOptions.get(position);
if (item != null) {
((ImageView) convertView.findViewById(R.id.iv_icon)).setImageDrawable(item.icon);
((TextView) convertView.findViewById(R.id.tv_name)).setText(item.title);
return convertView;
}
return null;
}
}
Layout File For CropOptionAdapter
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:gravity="center_vertical">
<ImageView
android:id="#+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""/>
</LinearLayout>
This is the resultActivity.witch give the crop image.
/**
* #see android.app.Activity#onActivityResult(int, int, android.content.Intent)
*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) return;
switch (requestCode)
{
case CROP_FROM_CAMERA:
if (data == null)
{
genHelper.showToast("No Crop Activity in This");
return;
}
final Bundle extras = data.getExtras();
if (extras != null)
{
try
{
_tempOpration=extras.getParcelable("data");
imageLayout.setImageBitmap(_tempOpration);
_tempOpration=null;
}
catch (Exception e)
{
e.printStackTrace();
}
}
break;
}
}
//Do This Type It's work on my live app.
genHelper.showToast("No Crop Activity in This");
is my general Class to help display toast message and Error Log.
Bestof Luck.
First, variables:
final int PIC_CROP = 2;
Uri imageUri;
Bitmap thePic;
Before you take a pic from your Camera or your Gallery, put your image into a Uri (imageUri) , use a method called here as "performCrop()" inside try/catch:
private void performCrop(){
try {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getPackageManager().queryIntentActivities( intent, 0 );
int size = list.size();
if (size >= 0) {
intent.setData(imageUri);
intent.putExtra("crop", "false");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 256);
intent.putExtra("outputY", 256);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, 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();
}
}
On method onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if(requestCode == PIC_CROP){
if (resultCode == RESULT_OK) {
Bundle extras = intent.getExtras();
thePic = extras.getParcelable("data");
imageViewPhoto.setImageBitmap(thePic); //in my case, set the image on screen
}else{
//do something
}
}
}
As mentioned in similar threads, Android does not have an official crop intent
(https://commonsware.com/blog/2013/01/23/no-android-does-not-have-crop-intent.html), so I would stay away from using "com.android.camera.action.CROP".
However, in the time since this question was originally posted, Android has added a new API in Kitkat (level 19) that allows users to summon a crop-this-image-and-set-as-wallpaper Activity. See WallpaperManager.getCropAndSetWallpaperIntent(), and this might address your original question.
I also had the problem using the camera and ACTION_PICK that the returned image was very small despite the passed resolution being much larger. I got around this storing the resulted crop image in a temporary file
// temporary storage location, preferably in your cache directory
private final String tempFilePath = "somePath";
// URI instantiated with your temporary storage location
private Uri tempuri = Uri.fromFile(new File(tempFilePath));
// code for startActivityForResult
private final static int ACTIVITY_CROP_IMAGE = 1;
and calling the intent like this
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("crop", "true");
photoPickerIntent.putExtra("aspectX", wallpaperWidth);
photoPickerIntent.putExtra("aspectY", wallpaperHeight);
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempuri);
photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(photoPickerIntent, ACTIVITY_CROP_IMAGE);
and then in onActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode != RESULT_OK)
return;
if(requestCode == ACTIVITY_CROP_IMAGE)
{
try
{
Bitmap bmp = BitmapFactory.decodeFile(tempFilePath);
if(bmp != null)
{
WallpaperManager myWallpaperManager = WallpaperManager.getInstance(getApplicationContext());
myWallpaperManager.setBitmap(bmp);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if(tempFilePath != null)
{
File tempFile = new File(tempFilePath);
if(tempFile.exists())
{
tempFile.delete();
}
}
}
}
}
I constructed the above code from the top of my head and didn't actually compile any of it. But the basics are correct and you should get the hang ;-)

Android crop image after taken

I am trying to let to user crop images after taking them / choosing from gallery. Now, the cropping after selecting from gallery works but not camera. Below are my codes, I am not getting any error message. We followed http://mobile.tutsplus.com/tutorials/android/capture-and-crop-an-image-with-the-device-camera/
//Camera button clicked
public void camera_click(View view) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra("return-data", true);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
//Result of camera capture
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
//camera
if (requestCode == CAMERA_PIC_REQUEST) {
mImageCaptureUri = data.getData();
performCrop();
}
if (requestCode == PIC_CROP) {
//get the returned data
try{
Bundle extras = data.getExtras();
//get the cropped bitmap
thumbnail = extras.getParcelable("data");
//retrieve a reference to the ImageView
ImageView image = (ImageView) findViewById(R.id.test_image);
//display the returned cropped image
image.setImageBitmap(thumbnail);
TextView imgTv = (TextView) findViewById(R.id.imageInfo);
String desc = imgTv.getText().toString();
if (desc.equalsIgnoreCase("")) {
String errorMessage = "Please enter a description before submitting a photo.";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
} else {
}
}
catch(Exception ex)
{
Log.i("err", ex.getMessage());
}
}
//gallery selected
if (requestCode == SELECT_PHOTO) {
if (data != null) {
Cursor cursor = getContentResolver().query(data.getData(), null, null, null, null);
cursor.moveToFirst(); //if not doing this, 01-22 19:17:04.564: ERROR/AndroidRuntime(26264): Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
int idx = cursor.getColumnIndex(ImageColumns.DATA);
String fileSrc = cursor.getString(idx);
thumbnail = BitmapFactory.decodeFile(fileSrc); //load preview image
thumbnail = android.graphics.Bitmap.createScaledBitmap(thumbnail, 100, 100, true);
// ImageView image = (ImageView) findViewById(R.id.test_image);
// image.setImageBitmap(thumbnail);
ImageButton cam = (ImageButton) findViewById(R.id.camera);
// cam.setVisibility(View.INVISIBLE);
ImageButton gal = (ImageButton) findViewById(R.id.gallery);
mImageCaptureUri = data.getData();
// gal.setVisibility(View.INVISIBLE);
performCrop();
} else {
//Log.d(LOG_TAG, "idButSelPic Photopicker canceled");
// m_Tv.setText("Image selection canceled!");
}
}
}
}//end onactivity results
//method to luanch crop image
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");
cropIntent.setDataAndType(mImageCaptureUri, "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, PIC_CROP);
} catch (ActivityNotFoundException anfe) {
//display an error message
Log.i("err", anfe.getLocalizedMessage());
String errorMessage = "Your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
Intent myIntent = new Intent();
startActivityForResult(myIntent, PIC_CROP);
}
}
This line is probably giving you this problem:
mImageCaptureUri = data.getData();
Delete this and check it out.
If not, I could give you a working code.
Working sample:
Include also this library: https://github.com/lvillani/android-cropimage
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
switch (requestCode) {
case PICK_FROM_CAMERA:
doCrop();
break;
case PICK_FROM_FILE:
if(data != null){
mImageCaptureUri = data.getData();
doCrop();
}
break;
case CROP_FROM_CAMERA:
if(data != null){
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap photo = extras.getParcelable("data");
imagebutton.setImageBitmap(photo);
imagebutton.setScaleType(ScaleType.FIT_XY);
}
File f = new File(mImageCaptureUri.getPath());
if (f.exists()) f.delete();
}
break;
}
}
private void doCrop() {
// TODO Auto-generated method stub
final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
Intent intent = new Intent("com.android.camera.action.CROP");
// intent.setClassName("com.android.camera", "com.android.camera.CropImage");
intent.setType("image/*");
List<ResolveInfo> list = getActivity().getPackageManager().queryIntentActivities( intent, 0 );
int size = list.size();
if (size == 0) {
Toast.makeText(getActivity(), "Can not find image crop app", Toast.LENGTH_SHORT).show();
return;
} else {
intent.setData(mImageCaptureUri);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
if (size == 1) {
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, CROP_FROM_CAMERA);
} else {
for (ResolveInfo res : list) {
final CropOption co = new CropOption();
co.title = getActivity().getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
co.icon = getActivity().getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
co.appIntent= new Intent(intent);
co.appIntent.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
cropOptions.add(co);
}
CropOptionAdapter adapter = new CropOptionAdapter(getActivity(), cropOptions);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Choose Crop App");
builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dialog, int item ) {
startActivityForResult( cropOptions.get(item).appIntent, CROP_FROM_CAMERA);
}
});
builder.setOnCancelListener( new DialogInterface.OnCancelListener() {
#Override
public void onCancel( DialogInterface dialog ) {
if (mImageCaptureUri != null ) {
getActivity().getContentResolver().delete(mImageCaptureUri, null, null );
mImageCaptureUri = null;
}
}
} );
AlertDialog alert = builder.create();
alert.show();
}
}
}
CropOption class:
public class CropOption {
public CharSequence title;
public Drawable icon;
public Intent appIntent;
}
CropOptionAdapter:
public class CropOptionAdapter extends ArrayAdapter<CropOption> {
private ArrayList<CropOption> mOptions;
private LayoutInflater mInflater;
public CropOptionAdapter(Context context, ArrayList<CropOption> options) {
super(context, R.layout.crop_selector, options);
mOptions = options;
mInflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup group) {
if (convertView == null)
convertView = mInflater.inflate(R.layout.crop_selector, null);
CropOption item = mOptions.get(position);
if (item != null) {
((ImageView) convertView.findViewById(R.id.iv_icon)).setImageDrawable(item.icon);
((TextView) convertView.findViewById(R.id.tv_name)).setText(item.title);
return convertView;
}
return null;
}
}

Crop saved Image using com.android.camera.action.CROP on android

I have reads many question about this, but I still failed using this code... maybe anyone can corect my code... I want to crop an image from file that i know the location using com.android.camera.action.CROP like this...
mImageCaptureUri = Uri.fromFile(f);
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
intent.setData(mImageCaptureUri);
intent.putExtra("crop", true);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
Bundle extras = intent.getExtras();
if (extras != null) {
Bitmap photo = extras.getParcelable("intent");
tampilan.setImageBitmap(photo);
}
File f = new File(mImageCaptureUri.getPath());
if (f.exists()) f.delete();
But when i run the code, nothing hapend... T.T
can anyone help me??
I had modify my code and its works successfull, this is my code..
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/*");
List<ResolveInfo> list = getPackageManager().queryIntentActivities( intent, 0 );
int size = list.size();
if (size == 0) {
Toast.makeText(this, "Can not find image crop app", Toast.LENGTH_SHORT).show();
return;
} else {
intent.setData(selectImageUri);
intent.putExtra("outputX", 300);
intent.putExtra("outputY", 300);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
if (size == 1) {
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, CROP_RESULT);
} else {
}
}
and the activityResult like this
if (resultCode == RESULT_OK){
switch (requestCode){
case SELECT_PICTURE :
selectImageUri = data.getData();
doCrop();
break;
case CROP_RESULT :
Bundle extras = data.getExtras();
if (extras != null) {
bmp = extras.getParcelable("data");
temporary.setBitmap(bmp);
}
File f = new File(selectImageUri.getPath());
if (f.exists()) f.delete();
Intent inten3 = new Intent(this, tabActivity.class);
startActivity(inten3);
break;
case CAMERA_IMAGE :
doCrop();
break;
}
}
maybe its useful :D
Using this intent is very risky. It's not even a part of the documentation. Here's some more explanation about why it's a risky thing.
I suggest using a third party library for cropping, like this one.
Then start the activity, use this
startActivityForResult(intent, 1);
then use the following to get croped image
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK)return;
switch (requestCode) {
case 1:
Bundle extras = data.getExtras();
if (extras != null) {
photo = extras.getParcelable("data");
tampilan.setBitmap(photo);
break;
}
}
}
try {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(mPhotoUri, "image/*");
intent.putExtra("crop", "true");
Integer altura = documento.getAltura();
Integer largura = documento.getLargura();
if (altura != null && largura != null) {
intent.putExtra("aspectY", altura);
intent.putExtra("aspectX", largura);
}
File file = imagemProcessor.getNewFile();
mCropUri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mCropUri);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, REQUEST_IMAGE_CROP);
} catch (ActivityNotFoundException e) {
Context context = getBaseContext();
Toast toast = Toast.makeText(context, "Your device doesn't support the crop action!", Toast.LENGTH_SHORT);
toast.show();
} catch (IOException e) {
Context context = getBaseContext();
Toast toast = Toast.makeText(context, "Fail to create file!", Toast.LENGTH_SHORT);
toast.show();
}

Categories

Resources