Crop intent not working for images taken from camera - android

The problem i am facing is i have 2 options take picture from camera or gallery.....if the user chooses the camera then the image is stored on the sdcard and then showed to user for cropping....but problem is when i try to crop that image it shows cannot load the image.....
P.S if the same image is selected from gallery option then there is no problem and im able to crop the image smoothly...any help would be appreciated
FYI.... i am getting the path of the image also
private void performCrop(Uri path) {
// take care of exceptions
try {
Log.d(TAG,"path is in perform crop"+path);
// 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(path,"image/*");
// set crop properties
cropIntent.putExtra("crop", "true");
// indicate aspect of desired crop
cropIntent.putExtra("aspectX", 0);
cropIntent.putExtra("aspectY", 0);
// 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, CROP_PIC);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe) {
Toast toast = Toast
.makeText(this, "This device doesn't support the crop action!", Toast.LENGTH_SHORT);
toast.show();
}catch (Exception e){
e.printStackTrace();
}
}

Related

Cropped image not working with tess-two

I am creating an app that can capture image through camera and can extract the text in the image using tess-two library of android.
The code works fine until I added the option of cropping the image. After cropping the image the error occurs on the line
tessbaseAPI.setImage(bitmap)
The log says
Failed to read bitmap
Below is my code for cropping the image
private void performCrop() {
// take care of exceptions
try {
Log.v(TAG, "Inside try of performCrop");
// 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", 2);
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
Log.v(TAG, "Going to onActivityResult now");
startActivityForResult(cropIntent, CROP_PIC);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe) {
Toast toast = Toast
.makeText(this, "This device doesn't support the crop action!", Toast.LENGTH_SHORT);
toast.show();
}
}
and for performing OCR
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
Log.v(TAG, "Request Code is REQUEST_IMAGE_CAPTURE");
picUri = data.getData();
performCrop();
} else if (requestCode == CROP_PIC) {
Log.v(TAG, "Request Code is CROP_PIC");
Bundle extras = data.getExtras();
Bitmap bitmap = extras.getParcelable("data");
TextView res = (TextView) findViewById(R.id.hello);
//imageView.setImageBitmap(imageBitmap);
//Image image = ImageIO.read(imageFile);
//BufferedImage buffimg = (BufferedImage) image;
//BufferedImage img = ImageHelper.convertImageToGrayscale(buffimg);
//ITesseract instance = new Tesseract(); // JNA Interface Mapping
//ITesseract instance = new Tesseract1(); // JNA Direct Mapping
//TessDataManager.initTessTrainedData(context);
if (isStoragePermissionGranted() == true) {
TessBaseAPI tessBaseAPI = new TessBaseAPI();
String path = Environment.getExternalStorageDirectory() + "/";
//String path = "/mnt/sdcard/";
tessBaseAPI.setDebug(true);
tessBaseAPI.init(path, "eng");
tessBaseAPI.setImage(bitmap);
String text = tessBaseAPI.getUTF8Text();
tessBaseAPI.end();
res.setText(text);
}
}} else {
TextView res = (TextView) findViewById(R.id.hello);
res.setText("Well damn");
}
}
}
A line from log
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.example.abc.snaptravel/com.example.abc.snaptravel.MainActivity}: java.lang.RuntimeException: Failed to read bitmap
I will appreciate any help. Thank you!
Well there were a LOT of problems that were coming up. Overall I think the main problem was that I wasn't able to access my SD card. I read somewhere that it is tough to access SD cards in HTC models and I was using an HTC model only.
I solved the problem by saving my cropped image in the internal memory and then giving that path to the tessbaseAPI.setImage(File file)
The crop function became this -
private void performCrop() {
// take care of exceptions
try {
Log.v(TAG, "Inside try of performCrop");
// 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", 2);
cropIntent.putExtra("aspectY", 1);
// indicate output X and Y
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
File dir=
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
output=new File(dir, "CameraContentDemo.jpg");
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(output));
// retrieve data on return
cropIntent.putExtra("return-data", false);
// start the activity - we handle returning in onActivityResult
Log.v(TAG, "Going to onActivityResult now");
startActivityForResult(cropIntent, CROP_PIC);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe) {
Toast toast = Toast
.makeText(this, "This device doesn't support the crop action!", Toast.LENGTH_SHORT);
toast.show();
}
}
and the onActivityResult() became this -
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
Log.v(TAG, "Request Code is REQUEST_IMAGE_CAPTURE");
picUri = data.getData();
performCrop();
} else if (requestCode == CROP_PIC) {
Log.v(TAG, "Request Code is CROP_PIC");
Bundle extras = data.getExtras();
//Bitmap bitmap = (Bitmap)extras.get("data");
TextView res = (TextView) findViewById(R.id.hello);
ImageView im = (ImageView)findViewById(R.id.imageView);
//im.setImageBitmap(bitmap);
//imageView.setImageBitmap(imageBitmap);
//Image image = ImageIO.read(imageFile);
//BufferedImage buffimg = (BufferedImage) image;
//BufferedImage img = ImageHelper.convertImageToGrayscale(buffimg);
//ITesseract instance = new Tesseract(); // JNA Interface Mapping
//ITesseract instance = new Tesseract1(); // JNA Direct Mapping
//TessDataManager.initTessTrainedData(context);
if (isStoragePermissionGranted() == true) {
TessBaseAPI tessBaseAPI = new TessBaseAPI();
String path = Environment.getExternalStorageDirectory() + "/";
//String path = "/mnt/sdcard/";
tessBaseAPI.setDebug(true);
tessBaseAPI.init(path, "eng");
File file = new File(picUri.getPath());
tessBaseAPI.setImage(output);
String text = tessBaseAPI.getUTF8Text();
tessBaseAPI.end();
res.setText(text);
}
}} else {
TextView res = (TextView) findViewById(R.id.hello);
res.setText("Well damn");
}
}
}
Note that I have done this -
cropIntent.putExtra("return-data", false);
We don't need data from this function when we are providing the file it is stored in.

Android: Saving Bitmap to External Memory

I'm currently working on a project of capturing an image, cropping the image, processing the image then saving the processed image. My problem lies in saving the processed image. I can't save the processed image. For every image that is captured, the captured image is being shown in the gallery instead of the processed image. I'm thinking that because the capturing image code saves the image to the SD card, I can't save the processed image that is on a bitmap... I hope you can enlighten me on what is the problem of my code. There is no error on the code by the way.
To be a little more specific, the app I'm working with captures image then crops the image. After that image will be shown in imageView. When processed, it will be again shown in an imageView. when i get the image to save in the external storage, nothing happens...
Here is the code for capturing and cropping the image
public class MainActivity extends Activity {
ImageView mainImageview;
Button mainButtonTakePhoto;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeControls();
}
private void initializeControls() {
mainImageview = (ImageView)findViewById(R.id.imageView1);
mainButtonTakePhoto = (Button)findViewById(R.id.button3);
mainButtonTakePhoto.setOnClickListener(new OnClickListener() {
#Override
public void onClick (View v) {
/* create an instance of intent
* pass action android.media.action.IMAGE_CAPTURE
* as argument to launch camera */
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
/*create instance of File with name img.jpg*/
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "img.jpg");
/*put uri as extra in intent object*/
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
/*start activity for result pass intent as argument and request code */
startActivityForResult(intent, 1);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//if request code is same we pass as argument in startActivityForResult
if(requestCode==1){
//create instance of File with same name we created before to get image from storage
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "img.jpg");
//Crop the captured image using an other intent
try {
/*the user's device may not support cropping*/
cropCapturedImage(Uri.fromFile(file));
}
catch(ActivityNotFoundException aNFE){
//display an error message if user device doesn't support
String errorMessage = "Sorry - your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
if(requestCode==2){
//Create an instance of bundle and get the returned data
Bundle extras = data.getExtras();
//get the cropped bitmap from extras
Bitmap thePic = extras.getParcelable("data");
//set image bitmap to image view
mainImageview.setImageBitmap(thePic);
}
}
//create helping method cropCapturedImage(Uri picUri)
public void cropCapturedImage(Uri picUri){
//call the standard crop action intent
Intent cropIntent = new Intent("com.android.camera.action.CROP");
//indicate image type and Uri of image
cropIntent.setDataAndType(picUri, "image/*");
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 0);
cropIntent.putExtra("aspectY", 0);
//indicate output X and Y
cropIntent.putExtra("outputX", 128);
cropIntent.putExtra("outputY", 256);
//retrieve data on return
cropIntent.putExtra("return-data", true);
//start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, 2);
}
}
And here is the code for saving the image.
public void saveImageToExternalStorage(Bitmap finalBitmap) {
String root =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file1 = new File(myDir, fname);
if (file1.exists())
file1.delete();
try {
FileOutputStream out = new FileOutputStream(file1);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
}
catch (Exception e) {
e.printStackTrace();
}
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this, new String[] { file1.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
}
Thanks a lot for your help. I'm trying not to trouble anyone if this is a stupid question. And I'm really trying my best to research and study every part of the code I'm using/lifting... Thanks again...
Are you testing it on api23 and up? If so... are you manually requesting permission to WRITE_EXTERNAL_STORAGE? because putting it in manifest is not enough.
The code works just fine... I'm sorry to waste all of your time and concern...
I just added the manifest to write to memory...
When I read from android developers about the manifest for writing to storage, I thought there is no need for the manifest when you are using API19 and up...

refactor performCrop() method out of activity class

I have a PerformCrop method which works perfectly.
I want to move it to my 'util' class so i can call it in other activities. There are complications to this in that it uses intents which return to the calling class. I think this should be no issue but maybe i'm incorrect.
Here is what i have tried and the issue i am seeing
I cut and paste performCrop() to my util class.
I had an error at 'startActivityForResult(cropIntent, CROP_IMAGE);' where it didnt recognise the method so i extended the class with 'Extends Activity'
When it runs it errors and im not 100% sure why but an exception is caught
'java.lang.NullPointerException: Attempt to invoke virtual method
'android.app.ActivityThread$ApplicationThread
android.app.ActivityThread.getApplicationThread()' on a null object
reference'
Here is the method, below that is the 'onActivityResult' method. Can anyone tell me how to move the performCrop() to a non Activity extended class?
Code
public void performCrop(Uri picUri)
{
final int CROP_IMAGE = 2;
/*
* PERFORM CROP
* this must take into account he fact we may not have a crop method on phone, or the diff ways diff OS crop
*/
//NEXUS 5 OS 5 is example of this branch
// 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);
// // // indicate output X and Y
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, CROP_IMAGE);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe)
{
Toast toast = Toast.makeText(this,"This device doesn't support the crop action! Exception: " + anfe.toString(),Toast.LENGTH_SHORT);
toast.show();
}
catch (OutOfMemoryError e)
{//NOT TESTED AS HW DOES NOT GO HERE
System.out.println("out of memory");
}
catch (Exception e)
{ //NOT TESTED AS HW DOES NOT GO HERE
Display display = this.getWindowManager().getDefaultDisplay();
Point size = new Point();
//display.getSize(size);
int width = size.x;
int height = size.y;
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", 2);
cropIntent.putExtra("aspectY", 1);
// // indicate output X and Y
cropIntent.putExtra("outputX", width);
cropIntent.putExtra("outputY", 200);
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, CROP_IMAGE);
}
}
Called from Activity when the camera intent returns successful result. Note the crop intent will also retun to this method.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
// TODO Auto-generated method stub
if (resultCode==RESULT_OK )
{
if(requestCode == CAMERA_IMAGE) //reply from camera
{
toolbox.performCrop(uri); //crop the picture
}
if(requestCode == CROP_IMAGE) //reply from crop
{
/* Bitmap bmp = getBitmap(uri);
imgView.setImageBitmap(bmp);*/
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap bmp = extras.getParcelable("data");
imgViewProfilePic.setImageBitmap(bmp);
}
}
if (requestCode == PICK_IMAGE_FROM_GALLERY) //reply from gallery
{
Uri selectedImage = data.getData();
uri = data.getData();
toolbox.performCrop(uri);
}
}
}
Create A Class name CropImage, put your method performCrop() in it and call it from wherever you want as,
CropImage cropImage = new CropImage(this);
cropImage.performCrop(uri);
The CropImage claas would look like,
public class CropImage {
Context context;
public CropImage(Context context) {
this.context = context;
}
public void performCrop(Uri picUri)
{
final int CROP_IMAGE = 2;
/*
* PERFORM CROP
* this must take into account he fact we may not have a crop method on phone, or the diff ways diff OS crop
*/
//NEXUS 5 OS 5 is example of this branch
// 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);
// // // indicate output X and Y
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
((Activity)context).startActivityForResult(cropIntent, CROP_IMAGE);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe)
{
Toast toast = Toast.makeText(context,"This device doesn't support the crop action! Exception: " + anfe.toString(), Toast.LENGTH_SHORT);
toast.show();
}
catch (OutOfMemoryError e)
{//NOT TESTED AS HW DOES NOT GO HERE
System.out.println("out of memory");
}
catch (Exception e)
{ //NOT TESTED AS HW DOES NOT GO HERE
Display display = ((Activity)context).getWindowManager().getDefaultDisplay();
Point size = new Point();
//display.getSize(size);
int width = size.x;
int height = size.y;
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", 2);
cropIntent.putExtra("aspectY", 1);
// // indicate output X and Y
cropIntent.putExtra("outputX", width);
cropIntent.putExtra("outputY", 200);
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
((Activity)context).startActivityForResult(cropIntent, CROP_IMAGE);
}
}
}
First You Check The Where Result Going
ifgetpaternt==null)
{
Startactivityforreslt(your intent,code);
}
else
{
getpaprent().Startactivityforreslt(your intent,code);
}
If Getpaprent() method call Then result send to parent activity .
so get result in parent activity and resend to your activity .....

Intent chooser stays open when using a Thread to get an image resource

I am building a photo upload form which has to grab an image either from the camera or gallery or whatever other resource is available (Dropbox/Google Drive/Astro File Manager, etc.). I think I have it all working except for one small component.
When the selected image is coming from a network resource, such as Google Drive, it can take a long time to return back to the activity. I would like to make this asynchronous to avoid having the user stare at a black screen while the image downloads.
There's a lot of code that I've written to get this whole thing to work, but here's the general process of it:
The Activity starts and displays the form.
The Intent chooser automatically opens and asks the user to select an image from either the camera or another app.
The user selects some app such as Google Drive, selects an image and that app closes, returning the selected image Uri as the result.
Cache the contents of the file to workaround KitKat permissions which can block from re-reading the image if the Activity closes and needs to resume.
Asynchronously display the scaled bitmap using the cached file as the source.
The Intent chooser closes, the image is displayed in an ImageButton and the form is visible to the user to be filled out before submission.
Once the submit button is tapped, an asynchronous task starts which allows for the multipart upload to the server.
The asynchronous upload uses a callback function to notify the user of the upload progress.
I'm getting stuck in the transition between #3 and #4.
If I use a Thread or AsyncTask
The Intent chooser will remain open, but the image will also be displayed on the form.
If I simply force the user to wait (serially)
The user is stuck looking at a black screen, then the Intent Chooser closes and the image is displayed on the form.
Opening the Intent chooser
/**
* see http://stackoverflow.com/a/12347567/940217
*/
private void openImageIntent() {
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final PackageManager packageManager = getPackageManager();
Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File photoFile;
try {
uploadableImage.makeCameraTempFile();
photoFile = uploadableImage.getCameraTempFile();
uploadableImage.setCameraFilepath(photoFile.getAbsolutePath());
} catch (IOException ex) {
// Error occurred while creating the File
photoFile = null;
uploadableImage.invalidate();
Log.e(TAG, "Error while creating the temporary file needed for image capture from camera.");
ex.printStackTrace();
}
// Continue only if the File was successfully created
if (photoFile != null && packageManager != null) {
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
// Create the File where the photo should go
if (res.activityInfo == null) {
continue;
}
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
cameraIntents.add(intent);
}
} else {
Toast.makeText(this, "Could not make temporary file.", Toast.LENGTH_LONG).show();
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.size()]));
startActivityForResult(chooserIntent, REQUEST_IMAGE_CAPTURE);
}
onActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_IMAGE_CAPTURE) {
if (tempUpFile != null){
tempUpFile.invalidate();
}
if (data == null) {
Log.d(TAG, "Data was null -- source was from camera");
uploadableImage.preserveCameraFile();
setPic();
} else {
Uri selectedImageUri = data.getData();
if (selectedImageUri == null) {
Log.e(TAG, "An error that should never occur has occurred -- selectedImageUri was null when trying to get the data from the Image Capture activity result.");
Toast.makeText(this, "Unexpected error when trying to get an image from the gallery or file manager.", Toast.LENGTH_LONG).show();
return;
}
uploadableImage.setSourceImageUri(selectedImageUri, imageButton);
setPic(); // only do this if doing this serially.
}
} else if (resultCode == RESULT_CANCELED){
uploadableImage.invalidate();
if (tempUpFile != null){
uploadableImage = tempUpFile;
}
setPic();
}
}
UploadableImage#setSourceImageUri
public void setSourceImageUri(Uri selectedImageUri, final ImageView iView) {
// Important!! - clean up after ourselves!
deleteFile(this.cameraFile);
this.cameraFile = null;
InputStream tempInStream = null;
OutputStream tempOutStream = null;
try {
this.cacheFile = createFile();
tempInStream = context.getContentResolver().openInputStream(selectedImageUri);
tempOutStream = new FileOutputStream(this.cacheFile);
} catch (IOException e) {
Toast.makeText(context, "Error while trying to read the selected image.", Toast.LENGTH_LONG).show();
Log.e(TAG, "IOException while trying to copy the selected image to our cache file");
e.printStackTrace();
}
if (tempInStream == null || tempOutStream == null){
Toast.makeText(context, "Error while trying to "+(tempInStream == null ? "read" :"store")+" the selected image.", Toast.LENGTH_LONG).show();
Log.e(TAG, "Error while trying to get the " + (tempInStream == null ? "input" : "output") + " stream");
return;
}
// Works, but makes the UI hang on a black screen while waiting for the resource.
try {
copy(tempInStream, tempOutStream);
}catch (IOException e){
Toast.makeText(context, "Error while trying to read the selected image.", Toast.LENGTH_LONG).show();
Log.e(TAG, "IOException while trying to copy the selected image to our cache file");
e.printStackTrace();
}
/*
// Works, but leaves the IntentChooser open
final InputStream inStream = tempInStream;
final OutputStream outStream = tempOutStream;
new Thread(new Runnable() {
public void run() {
try {
copy(inStream, outStream);
// FIXME: somehow notify/display the bitmap in the UI
// --maybe use Message and Handler? callback Interface?
} catch (IOException e) {
Toast.makeText(context, "Error while trying to read the selected image.", Toast.LENGTH_LONG).show();
Log.e(TAG, "IOException while trying to copy the selected image to our cache file");
e.printStackTrace();
}
}
}).start();
*/
}
Edit:
I've found that this will/will not occur depending on API level.
Does not occur:
KitKat (Nexus 4)
ICS MR1 (emulator)
Does occur:
KitKat (emulator)
ICS MR1 (Galaxy Tab 10.1)
Edit 2:
Here are some screenshots of what should not happen; images are from KitKat emulator.
Start the Activity
Select an image from the gallery or some other resource
The onActivityResult returns and the chooser remains open
This is how it should look after onActivityResult
Feeling pretty stupid, but I found the solution.
The issue was in step two: "The Intent chooser automatically opens..."
In order to do this, I was checking to see if a bitmap was available, and if it wasn't then it should display the placeholder image and then open the Intent chooser. I had this logic inside the onStart method which normally gets run after onActivityResult. However, because this was all happening asynchronously, I could not rely on this order.
What I had to do was put in a boolean flag which could tell me if we were waiting for a bitmap, and then not open the chooser if we were.

Crop an Image by passing the image file path in Android

I have tried the below code. However, it always results the 160*160 dimension image.
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(Uri.fromFile(pictureFile), "image/*");
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 100);
cropIntent.putExtra("aspectY", 100);
cropIntent.putExtra("scale", true);
//indicate output X and Y
cropIntent.putExtra("outputX", 500);
cropIntent.putExtra("outputY", 500);
//retrieve data on return
cropIntent.putExtra("return-data", true);
//start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, CROP_IMAGE);
} catch(ActivityNotFoundException anfe) {
//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();
}
I would like to crop an image by passing its path.
I don't want to capture/pick from default camera app or gallery. Please help me on this.
I have solved this by create a new file before calling Intent and passing this file path to store the cropped image through intent. Here is the solution for this.
private Uri mCropImagedUri;
private final int CROP_IMAGE = 100;//unique request code number. Which is used to identify the request result in onActivityResult()
/**Crop the image
* #return returns <tt>true</tt> if crop supports by the device,otherwise false*/
private boolean performCropImage(){
try {
if(mFinalImageUri!=null){
//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(mFinalImageUri, "image/*");
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("scale", true);
//indicate output X and Y
cropIntent.putExtra("outputX", 500);
cropIntent.putExtra("outputY", 500);
//retrieve data on return
cropIntent.putExtra("return-data", false);
File f = createNewFile("CROP_");
try {
f.createNewFile();
} catch (IOException ex) {
VLLog.e("io", ex.getMessage());
}
mCropImagedUri = Uri.fromFile(f);
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCropImagedUri);
//start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, CROP_IMAGE);
return true;
}
}
catch(ActivityNotFoundException anfe){
//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();
return false;
}
return false;
}
private File createNewFile(String prefix){
if(prefix==null || "".equalsIgnoreCase(prefix)){
prefix="IMG_";
}
File newDirectory = new File(Environment.getExternalStorageDirectory()+"/mypics/");
if(!newDirectory.exists()){
if(newDirectory.mkdir()){
VLLog.d(mContext.getClass().getName(), newDirectory.getAbsolutePath()+" directory created");
}
}
File file = new File(newDirectory,(prefix+System.currentTimeMillis()+".jpg"));
if(file.exists()){
//this wont be executed
file.delete();
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
So here we should not bother about the data which comes in onActivityResult() method.
Here is the complete information about cropping image. I have used this to solve.
http://www.androidworks.com/crop_large_photos_with_android
Android doesn't support a cropping intent built in. You should not assume it's available.
Instead you should use your own solution, or use a third party library, like this one:
https://github.com/ArthurHub/Android-Image-Cropper
Read more about it here:
https://commonsware.com/blog/2013/01/23/no-android-does-not-have-crop-intent.html
In this way,you can scale the image:
Bitmap.createScaledBitmap(bitmap,50,50,true);

Categories

Resources