Allow user to crop image

It's hard for me to figure out how to allow the user to crop the picture. I would like to pass a bitmap variable with a loaded bitmap to crop the image before setting it as wallpaper. But I can’t do it ... That's what I tried.

First version. = It works as expected, but the returned image is in poor resolution. Changing the output to a larger value does not help. As I saw in some posts, it is not recommended to use the 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); 

Secondly. Download the selected image snapshot and then crop it. How to configure it to load the crop directly to my image? As 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 the result of onActivity

 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 don’t know that these are the right ways to do this, but I hope someone can point me in the right direction. What, why and how to use.

Update: I am still waiting for someone to indicate how to do this correctly, the answers below work, but return low resolution images, so they cannot use

+7
source share
4 answers

Good. Honey, I put all my Crop Image code on Android. This is a 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 another use of the class used to determine the target yield action in an application.

Class CropOption.

 public class CropOption { public CharSequence title; public Drawable icon; public Intent appIntent; } 

this is used to display the 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 result resultActivity.witch gives the cropping 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 This works in my live application.

genHelper.showToast ("No Crop Activity in This");

is my general class that helps display toasts and error logs.

Best luck.

+3
source

Firstly, the variables are:

 final int PIC_CROP = 2; Uri imageUri; Bitmap thePic; 

Before taking a picture from your camera or your gallery, put your image in Uri (imageUri), use the 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(); } } 

In the onActivityResult method:

 @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 } } } 
+2
source

As mentioned in similar threads, Android has no official intention ( https://commonsware.com/blog/2013/01/23/no-android-does-not-have-crop-intent.html ), so I will not use "com.android.camera.action.CROP".

However, at the time this question was originally posted, Android added a new API to Kitkat (level 19) that allows users to call Activity-this-image-and-set-as-wallpaper Activity. See WallpaperManager.getCropAndSetWallpaperIntent () and this may solve your original question.

+1
source

I also had a problem using the camera and ACTION_PICK that the returned image was very small, even though the accepted resolution is much larger. I went around this saving the resulting 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 this intention

 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 built the code above from the top of my head and did not actually compile it. But the basics are correct, and you should get stuck; -)

-2
source

All Articles