Closed mayurxd closed 8 years ago
First implement
CropImageView.OnGetCroppedImageCompleteListener
and set listener
mCropImageView.setOnGetCroppedImageCompleteListener(this);
You can call
mCropImageView.getCroppedImageAsync(mCropImageView.getCropShape(), 0, 0);
method and than you can get callback in this method.
@Override
public void onGetCroppedImageComplete(CropImageView view, Bitmap bitmap, Exception error) {
if (error == null) {
storeImage(bitmap);
} else {
//Error
}
}
Store Image
private void storeImage(Bitmap image) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d(TAG,
"Error creating media file, check storage permissions: ");// e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
To Get the Path for Image Storage
private File getOutputMediaFile(){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ getApplicationContext().getPackageName()
+ "/Files");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
File mediaFile;
String mImageName="MI_"+ timeStamp +".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
i am getting errors
1) At app launch i am getting error as :- image crop failed width must be >0
2)App is now unstable and forced closing sometimes, showing this errors in logcat
02-08 18:39:43.434 15295-15295/com.example.croppersample E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.croppersample, PID: 15295 java.lang.NullPointerException at com.theartofdev.edmodo.cropper.sample.MainActivity.storeImage(MainActivity.java:256) at com.theartofdev.edmodo.cropper.sample.MainActivity.onGetCroppedImageComplete(MainActivity.java:333) at com.theartofdev.edmodo.cropper.CropImageView.onGetImageCroppingAsyncComplete(CropImageView.java:663) at com.theartofdev.edmodo.cropper.BitmapCroppingWorkerTask.onPostExecute(BitmapCroppingWorkerTask.java:154) at com.theartofdev.edmodo.cropper.BitmapCroppingWorkerTask.onPostExecute(BitmapCroppingWorkerTask.java:26) at android.os.AsyncTask.finish(AsyncTask.java:632) at android.os.AsyncTask.access$600(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5146) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566) at dalvik.system.NativeStart.main(Native Method)
here is my main activity
public class MainActivity extends Activity implements CropImageView.OnSetImageUriCompleteListener, CropImageView.OnGetCroppedImageCompleteListener {
//region: Fields and Consts
private static final int DEFAULT_ASPECT_RATIO_VALUES = 20;
private static final int ROTATE_NINETY_DEGREES = 90;
private static final String ASPECT_RATIO_X = "ASPECT_RATIO_X";
private static final String ASPECT_RATIO_Y = "ASPECT_RATIO_Y";
private static final int ON_TOUCH = 1;
private CropImageView mCropImageView;
private int mAspectRatioX = DEFAULT_ASPECT_RATIO_VALUES;
private int mAspectRatioY = DEFAULT_ASPECT_RATIO_VALUES;
Bitmap croppedImage;
//endregion
// Saves the state upon rotating the screen/restarting the activity
@Override
protected void onSaveInstanceState(@SuppressWarnings("NullableProblems") Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putInt(ASPECT_RATIO_X, mAspectRatioX);
bundle.putInt(ASPECT_RATIO_Y, mAspectRatioY);
}
// Restores the state upon rotating the screen/restarting the activity
@Override
protected void onRestoreInstanceState(@SuppressWarnings("NullableProblems") Bundle bundle) {
super.onRestoreInstanceState(bundle);
mAspectRatioX = bundle.getInt(ASPECT_RATIO_X);
mAspectRatioY = bundle.getInt(ASPECT_RATIO_Y);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
// Initialize components of the app
mCropImageView = (CropImageView) findViewById(R.id.CropImageView);
final SeekBar aspectRatioXSeek = (SeekBar) findViewById(R.id.aspectRatioXSeek);
final SeekBar aspectRatioYSeek = (SeekBar) findViewById(R.id.aspectRatioYSeek);
Spinner showGuidelinesSpin = (Spinner) findViewById(R.id.showGuidelinesSpin);
final TextView aspectRatioNum = (TextView) findViewById(R.id.aspectRatioNum);
if (savedInstanceState == null) {
mCropImageView.setImageResource(R.drawable.butterfly);
}
// Sets sliders to be disabled until fixedAspectRatio is set
aspectRatioXSeek.setEnabled(false);
aspectRatioYSeek.setEnabled(false);
// Set initial spinner value
showGuidelinesSpin.setSelection(ON_TOUCH);
//Sets the rotate button
final Button rotateButton = (Button) findViewById(R.id.Button_rotate);
rotateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCropImageView.rotateImage(ROTATE_NINETY_DEGREES);
}
});
// Sets fixedAspectRatio
((ToggleButton) findViewById(R.id.fixedAspectRatioToggle)).setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mCropImageView.setFixedAspectRatio(isChecked);
if (isChecked) {
aspectRatioXSeek.setEnabled(true);
aspectRatioYSeek.setEnabled(true);
} else {
aspectRatioXSeek.setEnabled(false);
aspectRatioYSeek.setEnabled(false);
}
}
});
// Sets crop shape
((ToggleButton) findViewById(R.id.cropShapeToggle)).setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mCropImageView.setCropShape(isChecked ? CropImageView.CropShape.OVAL : CropImageView.CropShape.RECTANGLE);
}
});
// Sets initial aspect ratio to 10/10, for demonstration purposes
mCropImageView.setAspectRatio(DEFAULT_ASPECT_RATIO_VALUES, DEFAULT_ASPECT_RATIO_VALUES);
aspectRatioXSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar aspectRatioXSeek, int progress, boolean fromUser) {
mAspectRatioX = Math.max(1, progress);
mCropImageView.setAspectRatio(mAspectRatioX, mAspectRatioY);
aspectRatioNum.setText("(" + mAspectRatioX + ", " + mAspectRatioY + ")");
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
aspectRatioYSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar aspectRatioYSeek, int progress, boolean fromUser) {
mAspectRatioY = Math.max(1, progress);
mCropImageView.setAspectRatio(mAspectRatioX, mAspectRatioY);
aspectRatioNum.setText("(" + mAspectRatioX + ", " + mAspectRatioY + ")");
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// Sets up the Spinner
showGuidelinesSpin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
switch (i) {
case 0:
mCropImageView.setGuidelines(CropImageView.Guidelines.OFF);
break;
case 1:
mCropImageView.setGuidelines(CropImageView.Guidelines.ON_TOUCH);
break;
case 2:
mCropImageView.setGuidelines(CropImageView.Guidelines.ON);
break;
}
}
public void onNothingSelected(AdapterView<?> adapterView) {
return;
}
});
final TextView snapRadiusNum = (TextView) findViewById(R.id.snapRadiusNum);
((SeekBar) findViewById(R.id.snapRadiusSeek)).setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mCropImageView.setSnapRadius(progress);
snapRadiusNum.setText(Integer.toString(progress));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
findViewById(R.id.Button_crop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCropImageView.getCroppedImageAsync(mCropImageView.getCropShape(), 0, 0);
}
});
findViewById(R.id.Button_load).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(getPickImageChooserIntent(), 200);
}
});
mCropImageView.setOnGetCroppedImageCompleteListener(this);
mCropImageView.getCroppedImageAsync(mCropImageView.getCropShape(), 0, 0);
}
static final String TAG = "YOUR-TAG-NAME";
private void storeImage(Bitmap image) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d(TAG,
"Error creating media file, check storage permissions: ");// e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
private File getOutputMediaFile(){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ getApplicationContext().getPackageName()
+ "/Files");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
File mediaFile;
String mImageName="MI_"+ timeStamp +".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
@Override
protected void onStart() {
super.onStart();
mCropImageView.setOnSetImageUriCompleteListener(this);
mCropImageView.setOnGetCroppedImageCompleteListener(this);
}
@Override
protected void onStop() {
super.onStop();
mCropImageView.setOnSetImageUriCompleteListener(null);
mCropImageView.setOnGetCroppedImageCompleteListener(null);
}
@Override
public void onSetImageUriComplete(CropImageView view, Uri uri, Exception error) {
if (error == null) {
Toast.makeText(mCropImageView.getContext(), "Image load successful", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mCropImageView.getContext(), "Image load failed: " + error.getMessage(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onGetCroppedImageComplete(CropImageView view, Bitmap bitmap, Exception error) {
if (error == null) {
croppedImage = bitmap;
ImageView croppedImageView = (ImageView) findViewById(R.id.croppedImageView);
croppedImageView.setImageBitmap(croppedImage);
//CapturePhotoUtils cp;
//cp.insertImage(bitmap,"","");
} else {
Toast.makeText(mCropImageView.getContext(), "Image crop failed: " + error.getMessage(), Toast.LENGTH_LONG).show();
}
if (error == null) {
storeImage(bitmap);
} else {
//Error
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
Uri imageUri = getPickImageResultUri(data);
((CropImageView) findViewById(R.id.CropImageView)).setImageUriAsync(imageUri);
}
}
/**
* Create a chooser intent to select the source to get image from.<br/>
* The source can be camera's (ACTION_IMAGE_CAPTURE) or gallery's (ACTION_GET_CONTENT).<br/>
* All possible sources are added to the intent chooser.
*/
public Intent getPickImageChooserIntent() {
// Determine Uri of camera image to save.
Uri outputFileUri = getCaptureImageOutputUri();
List<Intent> allIntents = new ArrayList<>();
PackageManager packageManager = getPackageManager();
// collect all camera intents
Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
if (outputFileUri != null) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
}
allIntents.add(intent);
}
// collect all gallery intents
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
List<ResolveInfo> listGallery = packageManager.queryIntentActivities(galleryIntent, 0);
for (ResolveInfo res : listGallery) {
Intent intent = new Intent(galleryIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
allIntents.add(intent);
}
// the main intent is the last in the list (fucking android) so pickup the useless one
Intent mainIntent = allIntents.get(allIntents.size() - 1);
for (Intent intent : allIntents) {
if (intent.getComponent().getClassName().equals("com.android.documentsui.DocumentsActivity")) {
mainIntent = intent;
break;
}
}
allIntents.remove(mainIntent);
// Create a chooser from the main intent
Intent chooserIntent = Intent.createChooser(mainIntent, "Select source");
// Add all other intents
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toArray(new Parcelable[allIntents.size()]));
return chooserIntent;
}
/**
* Get URI to image received from capture by camera.
*/
private Uri getCaptureImageOutputUri() {
Uri outputFileUri = null;
File getImage = getExternalCacheDir();
if (getImage != null) {
outputFileUri = Uri.fromFile(new File(getImage.getPath(), "pickImageResult.jpeg"));
}
return outputFileUri;
}
/**
* Get the URI of the selected image from {@link #getPickImageChooserIntent()}.<br/>
* Will return the correct URI for camera and gallery image.
*
* @param data the returned data of the activity result
*/
public Uri getPickImageResultUri(Intent data) {
boolean isCamera = true;
if (data != null) {
String action = data.getAction();
isCamera = action != null && action.equals(MediaStore.ACTION_IMAGE_CAPTURE);
}
return isCamera ? getCaptureImageOutputUri() : data.getData();
}
public static void addImageToGallery(final String filePath, final Context context) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, filePath);
context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
}
mCropImageView.setOnGetCroppedImageCompleteListener(this);
mCropImageView.getCroppedImageAsync(mCropImageView.getCropShape(), 0, 0);
remove this two lines at end of oncreate method because this two lines already is there in your onStart method.. apart from it there is no issue in your code. i have tested your code in my project.
also change path
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/CropImages");
so you can see imges
Now when taking pic form camera it taking too long for cropping
i cannot see any image in gallery and is there any way i can make save button after cropping image which stores image in gallary
replace your two method and i have added code for publish image in galary..
static final String TAG = "YOUR-TAG-NAME";
private void storeImage(Bitmap image) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d(TAG,
"Error creating media file, check storage permissions: ");// e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, pictureFile.getPath());
getApplicationContext().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
private File getOutputMediaFile() {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
+ "/CropImages");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
File mediaFile;
String mImageName = "MI_" + timeStamp + ".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
@mayurxd did it worked for you? what were you missing in the library? do you have a suggestion? maybe a sample documentation that can help?
its working fine if want to save already existing image. on other hand if you take image from camera sometimes it do not works and couple of time i faced forced closed while editing and saving image taken by camera.
what i am doing wrong? here is my activity
public class MainActivity extends Activity implements CropImageView.OnSetImageUriCompleteListener, CropImageView.OnGetCroppedImageCompleteListener {
//region: Fields and Consts
private static final int DEFAULT_ASPECT_RATIO_VALUES = 20;
private static final int ROTATE_NINETY_DEGREES = 90;
private static final String ASPECT_RATIO_X = "ASPECT_RATIO_X";
private static final String ASPECT_RATIO_Y = "ASPECT_RATIO_Y";
private static final int ON_TOUCH = 1;
private CropImageView mCropImageView;
private int mAspectRatioX = DEFAULT_ASPECT_RATIO_VALUES;
private int mAspectRatioY = DEFAULT_ASPECT_RATIO_VALUES;
Bitmap croppedImage;
//endregion
// Saves the state upon rotating the screen/restarting the activity
@Override
protected void onSaveInstanceState(@SuppressWarnings("NullableProblems") Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putInt(ASPECT_RATIO_X, mAspectRatioX);
bundle.putInt(ASPECT_RATIO_Y, mAspectRatioY);
}
// Restores the state upon rotating the screen/restarting the activity
@Override
protected void onRestoreInstanceState(@SuppressWarnings("NullableProblems") Bundle bundle) {
super.onRestoreInstanceState(bundle);
mAspectRatioX = bundle.getInt(ASPECT_RATIO_X);
mAspectRatioY = bundle.getInt(ASPECT_RATIO_Y);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
// Initialize components of the app
mCropImageView = (CropImageView) findViewById(R.id.CropImageView);
final SeekBar aspectRatioXSeek = (SeekBar) findViewById(R.id.aspectRatioXSeek);
final SeekBar aspectRatioYSeek = (SeekBar) findViewById(R.id.aspectRatioYSeek);
Spinner showGuidelinesSpin = (Spinner) findViewById(R.id.showGuidelinesSpin);
final TextView aspectRatioNum = (TextView) findViewById(R.id.aspectRatioNum);
if (savedInstanceState == null) {
mCropImageView.setImageResource(R.drawable.butterfly);
}
// Sets sliders to be disabled until fixedAspectRatio is set
aspectRatioXSeek.setEnabled(false);
aspectRatioYSeek.setEnabled(false);
// Set initial spinner value
showGuidelinesSpin.setSelection(ON_TOUCH);
//Sets the rotate button
final Button rotateButton = (Button) findViewById(R.id.Button_rotate);
rotateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCropImageView.rotateImage(ROTATE_NINETY_DEGREES);
}
});
// Sets fixedAspectRatio
((ToggleButton) findViewById(R.id.fixedAspectRatioToggle)).setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mCropImageView.setFixedAspectRatio(isChecked);
if (isChecked) {
aspectRatioXSeek.setEnabled(true);
aspectRatioYSeek.setEnabled(true);
} else {
aspectRatioXSeek.setEnabled(false);
aspectRatioYSeek.setEnabled(false);
}
}
});
// Sets crop shape
((ToggleButton) findViewById(R.id.cropShapeToggle)).setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mCropImageView.setCropShape(isChecked ? CropImageView.CropShape.OVAL : CropImageView.CropShape.RECTANGLE);
}
});
// Sets initial aspect ratio to 10/10, for demonstration purposes
mCropImageView.setAspectRatio(DEFAULT_ASPECT_RATIO_VALUES, DEFAULT_ASPECT_RATIO_VALUES);
aspectRatioXSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar aspectRatioXSeek, int progress, boolean fromUser) {
mAspectRatioX = Math.max(1, progress);
mCropImageView.setAspectRatio(mAspectRatioX, mAspectRatioY);
aspectRatioNum.setText("(" + mAspectRatioX + ", " + mAspectRatioY + ")");
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
aspectRatioYSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar aspectRatioYSeek, int progress, boolean fromUser) {
mAspectRatioY = Math.max(1, progress);
mCropImageView.setAspectRatio(mAspectRatioX, mAspectRatioY);
aspectRatioNum.setText("(" + mAspectRatioX + ", " + mAspectRatioY + ")");
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// Sets up the Spinner
showGuidelinesSpin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
switch (i) {
case 0:
mCropImageView.setGuidelines(CropImageView.Guidelines.OFF);
break;
case 1:
mCropImageView.setGuidelines(CropImageView.Guidelines.ON_TOUCH);
break;
case 2:
mCropImageView.setGuidelines(CropImageView.Guidelines.ON);
break;
}
}
public void onNothingSelected(AdapterView<?> adapterView) {
return;
}
});
final TextView snapRadiusNum = (TextView) findViewById(R.id.snapRadiusNum);
((SeekBar) findViewById(R.id.snapRadiusSeek)).setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mCropImageView.setSnapRadius(progress);
snapRadiusNum.setText(Integer.toString(progress));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
findViewById(R.id.Button_crop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCropImageView.getCroppedImageAsync(mCropImageView.getCropShape(), 0, 0);
}
});
findViewById(R.id.Button_load).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(getPickImageChooserIntent(), 200);
}
});
}
static final String TAG = "YOUR-TAG-NAME";
private void storeImage(Bitmap image) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d(TAG,
"Error creating media file, check storage permissions: ");// e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, pictureFile.getPath());
getApplicationContext().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
private File getOutputMediaFile() {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
+ "/CropImages");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
File mediaFile;
String mImageName = "MI_" + timeStamp + ".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
@Override
protected void onStart() {
super.onStart();
mCropImageView.setOnSetImageUriCompleteListener(this);
mCropImageView.setOnGetCroppedImageCompleteListener(this);
}
@Override
protected void onStop() {
super.onStop();
mCropImageView.setOnSetImageUriCompleteListener(null);
mCropImageView.setOnGetCroppedImageCompleteListener(null);
}
@Override
public void onSetImageUriComplete(CropImageView view, Uri uri, Exception error) {
if (error == null) {
Toast.makeText(mCropImageView.getContext(), "Image load successful", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mCropImageView.getContext(), "Image load failed: " + error.getMessage(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onGetCroppedImageComplete(CropImageView view, Bitmap bitmap, Exception error) {
if (error == null) {
croppedImage = bitmap;
ImageView croppedImageView = (ImageView) findViewById(R.id.croppedImageView);
croppedImageView.setImageBitmap(croppedImage);
//CapturePhotoUtils cp;
//cp.insertImage(bitmap,"","");
} else {
Toast.makeText(mCropImageView.getContext(), "Image crop failed: " + error.getMessage(), Toast.LENGTH_LONG).show();
}
if (error == null) {
storeImage(bitmap);
} else {
//Error
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
Uri imageUri = getPickImageResultUri(data);
((CropImageView) findViewById(R.id.CropImageView)).setImageUriAsync(imageUri);
}
}
/**
* Create a chooser intent to select the source to get image from.<br/>
* The source can be camera's (ACTION_IMAGE_CAPTURE) or gallery's (ACTION_GET_CONTENT).<br/>
* All possible sources are added to the intent chooser.
*/
public Intent getPickImageChooserIntent() {
// Determine Uri of camera image to save.
Uri outputFileUri = getCaptureImageOutputUri();
List<Intent> allIntents = new ArrayList<>();
PackageManager packageManager = getPackageManager();
// collect all camera intents
Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
if (outputFileUri != null) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
}
allIntents.add(intent);
}
// collect all gallery intents
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
List<ResolveInfo> listGallery = packageManager.queryIntentActivities(galleryIntent, 0);
for (ResolveInfo res : listGallery) {
Intent intent = new Intent(galleryIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
allIntents.add(intent);
}
// the main intent is the last in the list (fucking android) so pickup the useless one
Intent mainIntent = allIntents.get(allIntents.size() - 1);
for (Intent intent : allIntents) {
if (intent.getComponent().getClassName().equals("com.android.documentsui.DocumentsActivity")) {
mainIntent = intent;
break;
}
}
allIntents.remove(mainIntent);
// Create a chooser from the main intent
Intent chooserIntent = Intent.createChooser(mainIntent, "Select source");
// Add all other intents
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, allIntents.toArray(new Parcelable[allIntents.size()]));
return chooserIntent;
}
/**
* Get URI to image received from capture by camera.
*/
private Uri getCaptureImageOutputUri() {
Uri outputFileUri = null;
File getImage = getExternalCacheDir();
if (getImage != null) {
outputFileUri = Uri.fromFile(new File(getImage.getPath(), "pickImageResult.jpeg"));
}
return outputFileUri;
}
/**
* Get the URI of the selected image from {@link #getPickImageChooserIntent()}.<br/>
* Will return the correct URI for camera and gallery image.
*
* @param data the returned data of the activity result
*/
public Uri getPickImageResultUri(Intent data) {
boolean isCamera = true;
if (data != null) {
String action = data.getAction();
isCamera = action != null && action.equals(MediaStore.ACTION_IMAGE_CAPTURE);
}
return isCamera ? getCaptureImageOutputUri() : data.getData();
}
public static void addImageToGallery(final String filePath, final Context context) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, filePath);
context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
}
you may have memory issues if you try to handle large bitmaps
setImageUriAsync()
will use down-sampling to lower the memory usage for the image, but in crop it will return the full sized bitmap when you use don't provide required width/height to getCroppedImageAsync
.
also in code you re-set the cropped image back to but then it can be very large to handle for rotation that may result in OOM.
if you do need to save a large image you may need to handle the cropping manually to save the stream without loading a bitmap into memory.
can you describe what are you trying to do.
images taken by the camera are around 2-8mb in size .
what i am doing is i wanted to save edited image so i can further use them in my app and apply zoom on it.
should work fine... make sure you release the bitmaps after cropping as soon as you done saving them to release the memory used by them. can you provides error details for the issues you see?
while handling images from camera its skipping frames
02-22 12:43:55.251 8504-8504/com.example.croppersample I/Choreographer: Skipped 771 frames! The application may be doing too much work on its main thread.
and then it crashed
02-22 12:44:19.071 8504-8504/com.example.croppersample I/Timeline: Timeline: Activity_launch_request id:com.android.camera2 time:28821841
02-22 12:44:28.851 8504-8504/com.example.croppersample W/ContextImpl: Failed to ensure directory: /storage/usbdisk0/Android/data/com.example.croppersample/cache
02-22 12:44:28.891 8504-8504/com.example.croppersample I/Adreno-EGL:
from what I can tell it hang in request to launch id:com.android.camera2
activity...
what action did you do right before the hang?
what device are you using?
i clicked on crop button right before it hanged ,and image was taken by camera while its skipping frames if you try to scroll or press an button that will cause the force closed. i am using redmi 2 with cynogenmod
that is very strange... you will have to debug it and find out which code hangs... try running the sample app, first too see if it happens there and second to add logs to spot the problematic code. Sorry that I can't be more helpful.
thanks for your all help :) i will try diff things , i will post if something works for me
after croping and rotaing how to save image into gallery in the new folder