how to get uri from Bitmap after cropping image was selected from gallery
i tried this
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.PNG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
but uri = null
i want to get uri from this
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST) {
Uri imageUri = data.getData();
performCrop(imageUri);
Log.e(TAG, "image before crop:" + imageUri);
}else if(resultCode == Activity.RESULT_OK && requestCode == PIC_CROP ){
// get the returned data
Bundle extras = data.getExtras();
// get the cropped bitmap
Bitmap selectedBitmap = extras.getParcelable("data");
getImageUri(this,selectedBitmap);
Uri ImageUri = data.getData();
Log.e(TAG, "image before crop:" + ImageUri);
log image before crop=null
---- UPDATE CROPPING----
private void performCrop(Uri picUri) {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
// indicate image type and Uri
cropIntent.setDataAndType(picUri, "image/*");
// set crop properties here
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", 128);
cropIntent.putExtra("outputY", 128);
// retrieve data on return
cropIntent.putExtra("return-data", true);
// start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, PIC_CROP);
}
// respond to users whose devices do not support the crop action
catch (ActivityNotFoundException anfe) {
// display an error message
String errorMessage = "Whoops - your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toast.show();
}
Im guessing you are selecting an image from your gallery.
perquisites:
Permissions in manifest to read/write data
Validation of permissions and handle no permissions granted case
Request code declared:
public static final int PICK_IMAGE = 1050;
(1)
Open image selector activity
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
In Activity:
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
In Fragment:
fragment.startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
(2) retrieving image from selection:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
if(resultCode == RESULT_OK && data != null && data.getData() != null ){
switch(requestCode){
case PICK_IMAGE_REQUEST:
//get filepath from the result of image selection
Uri filePath = data.getData();
//Start activity for result for crop for selected image
startCropActivity(filePath);
break;
case PIC_CROP:
// get the returned data
Bundle extras = data.getExtras();
// get the cropped bitmap
Bitmap selectedBitmap = extras.getParcelable("data");
//do whatever with the bitmap of the image
break;
}
}
}
Start Crop activity as so:
private void startCropActivity(Uri filePath){
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(filePath, "image/*");
cropIntent.putExtra("crop", true);
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("outputX", 128);
cropIntent.putExtra("outputY", 128);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, PIC_CROP);
}catch (ActivityNotFoundException anfe) {
// display an error message
Toast.makeText(this, "Could not crop", Toast.LENGTH_SHORT).show();
}
}
Related
if(requestCode == GET_FROM_GALLERY && resultCode == RESULT_OK) {
try {
Uri source_uri = imageUri;
Uri dest_uri = Uri.fromFile(new File(getCacheDir(), "cropped"));
// need to crop it to square image as CNN's always required square input
Crop.of(source_uri, dest_uri).asSquare().start(MainActivity.this);
} catch (Exception e) {
e.printStackTrace();
}
}
// if cropping acitivty is finished,
// get the resulting cropped image uri and send it
// to 'Classify' activity
else if(requestCode == Crop.REQUEST_CROP && resultCode == RESULT_OK) {
imageUri = Crop.getOutput(data);
Intent i = new Intent(MainActivity.this, Classify.class);
// put image data in extras to send
i.putExtra("resID_uri", imageUri);
// put filename in extras
i.putExtra("chosen", chosen);
// put model type in extras
i.putExtra("quant", quant);
// send other required data
startActivity(i);
}
This code is meant to select an image from gallery crop it and then send the cropped image output to the image classifier activity.
I had to set the button that picks the image as shown in the code with the model initialized as model= "model.tflite"
pick_image = findViewById(R.id.pick_picture);
pick_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// filename in assets
model = "model.tflite";
Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(gallery, GET_FROM_GALLERY);
}
});
then the onActivity has to look like the one below
if(requestCode == REQUEST_IMAGE && resultCode == RESULT_OK) {
try {
Uri source_uri = imageUri;
Uri dest_uri = Uri.fromFile(new File(getCacheDir(), "cropped"));
// need to crop it to square image as CNN's always required square input
Crop.of(source_uri, dest_uri).asSquare().start(MainActivity.this);
} catch (Exception e) {
e.printStackTrace();
}
}
// if cropping acitivty is finished, get the resulting cropped image uri and send it to 'Classify' activity
else if(requestCode == Crop.REQUEST_CROP && resultCode == RESULT_OK){
imageUri = Crop.getOutput(data);
Intent i = new Intent(MainActivity.this, Classify.class);
// put image data in extras to send
i.putExtra("resID_uri", imageUri);
// put filename in extras
i.putExtra("chosen", chosen);
// send other required data
startActivity(i);
}
if (requestCode == GET_FROM_GALLERY && resultCode == RESULT_OK){
// beginCrop(data.getData());
try{
Uri source =data.getData();
Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped"));
Crop.of(source, destination).asSquare().start(this);
}catch (Exception e){
e.printStackTrace();
}
}else if (requestCode == Crop.REQUEST_CROP && resultCode ==RESULT_OK){
// handleCrop(resultCode, data);
Uri gon = Crop.getOutput(data);
Intent i = new Intent(MainActivity.this, Classify.class);
// put image data in extras to send
i.putExtra("resID_uri", gon);
// put filename in extras
i.putExtra("chosen", chosen);
// send other required data
startActivity(i);
}
i'm writing an android app on java and need to let my users select and crop images from the gallery.
There is no problem when choosing an image from any native gallery, but when a user chooses to eater crop or choose an image from google photos app the app crushes.
I cannot figure out what is the source of the problem so any answer will be helpful
this is the code i'm using
class fields:
private Uri imageUri;
opening the camera:
private void camOpen() {
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(Environment.getExternalStorageDirectory(), "file" + String.valueOf(System.currentTimeMillis()) + ".png");
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
imageUri = Uri.fromFile(f);
i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
i.putExtra("return-data", true);
startActivityForResult(i, CAMERA_CODE);
}
opening the gallery:
private void galleryOpen() {
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(Intent.createChooser(i, "select file"), SELECT_PHOTO_CODE);
}
cropping the image:
private void cropImage() {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(imageUri, "image/*");
cropIntent.putExtra("crop", true);
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, CROP_CODE);
} catch (Exception e) {}
}
the result handler:
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_CODE && resultCode == Activity.RESULT_OK) {
cropImage();
} else if (requestCode == SELECT_PHOTO_CODE && resultCode == Activity.RESULT_OK) {
if (data != null) {
imageUri = data.getData();
cropImage();
}
} else if (requestCode == CROP_CODE && resultCode == Activity.RESULT_OK) {
Bundle bundle = data.getExtras();
Bitmap b = bundle.getParcelable("data");
hasImageChanged=true;
ivProfilePic.setImageBitmap(b);
capturedImage = b;
}
}
thank you for any useful help...
Android does not support crop intent because croping is not part of android api.
So i recommend you for Using library
the issue was with the crop intent. I ended up using the uCrop library and it fixed the problem.
When i press the button then the camera captures the picture, I want to perform crop on that picture after Cropping but i am unable to figure out the problem because crop function is not working properly, Please Help me to figure out the problem that is the main cause of crop function is not being preformed
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
final int CAMERA_CAPTURE = 1;
final int CROP_PIC = 2;
private Uri picUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button captureBtn = (Button) findViewById(R.id.capture_btn);
captureBtn.setOnClickListener((View.OnClickListener) this);
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.capture_btn) {
try {
// use standard intent to capture an image
Intent captureIntent = new Intent(
MediaStore.ACTION_IMAGE_CAPTURE);
// we will handle the returned data in onActivityResult
startActivityForResult(captureIntent, CAMERA_CAPTURE);
} catch (ActivityNotFoundException anfe) {
Toast toast = Toast.makeText(this, "This device doesn't support the crop action!",
Toast.LENGTH_SHORT);
toast.show();
}
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Toast toast4 = Toast.makeText(this, Integer.toString(RESULT_OK),
Toast.LENGTH_SHORT);
toast4.show();
if (resultCode == RESULT_OK) {
Toast toast = Toast.makeText(this, "capture ok",
Toast.LENGTH_SHORT);
toast.show();
if (requestCode == CAMERA_CAPTURE) {
// get the Uri for the captured image
picUri = data.getData();
// Toast toast1 = Toast.makeText(this, Integer.toString(requestCode),
// Toast.LENGTH_SHORT);
// toast1.show();
performCrop();
}
// user is returning from cropping the image
if (requestCode == CROP_PIC) {
Toast toast1 = Toast.makeText(this, "crop ok",
Toast.LENGTH_SHORT);
toast1.show();
// get the returned data
Bundle extras = data.getExtras();
// get the cropped bitmap
Bitmap thePic = extras.getParcelable("data");
ImageView picView = (ImageView) findViewById(R.id.picture);
picView.setImageBitmap(thePic);
}
}
}
/**
* this function does the crop operation.
*/
private void performCrop() {
////////////////// take care of exceptions
try {
// call the standard crop action intent (the user device may not
// support it)
Intent cropIntent = new Intent("com.android.camera.action.CROP");
// indicate image type and Uri
cropIntent.setDataAndType(picUri, "image/*");
// set crop properties
cropIntent.putExtra("crop", "true");
// indicate aspect of desired crop
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
// 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);
}
catch (ActivityNotFoundException anfe) {
Toast toast3 = Toast
.makeText(this, "This device doesn't support the crop action!", Toast.LENGTH_SHORT);
toast3.show();
}
}
}
I have these codes to get an image from gallery or take photo with camera and after cropping it i want to show it in a bitmap imageview.
My problem is they work good in some devices and don't work in others!
please tell me which part of my code is making the problem ! Thank you
For example:
On LG G4 i not able to crop , but the photo from gallery and camera shows on image view
On Samsung Galaxy Alpha i can crop , image from camera shows good but i cant choose from gallery!
What should i do to work fine in all devices?
private void showFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
// ******** code for crop image
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("cropped-rect", "true");
try {
intent.putExtra("return-data", true);
startActivityForResult(Intent.createChooser(intent,
"Complete action using"), PICK_FROM_GALLERY);
} catch (ActivityNotFoundException e) {
// Do nothing for now
}
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
private void captureWithCamera() {
// call android default camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString());
// ******** code for crop image
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 200);
intent.putExtra("outputY", 200);
intent.putExtra("cropped-rect", "true");
try {
intent.putExtra("return-data", true);
startActivityForResult(Intent.createChooser(intent,"Complete action using"), PICK_FROM_CAMERA);
} catch (ActivityNotFoundException e) {
// Do nothing for now
}
}
I think the problem must be in how i handle the returned data in onActivityResult method! Please take a look at my code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_FROM_GALLERY && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri filePath = data.getData();
try {
//Getting the Bitmap from Gallery
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
//Setting the Bitmap to ImageView
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
if (requestCode == PICK_FROM_CAMERA) {
Bundle extras = data.getExtras();
if (extras != null) {
//Bitmap photo = extras.getParcelable("data");
bitmap = extras.getParcelable("data");
imageView.setImageBitmap(bitmap);
}
}
}
Possible solutions would be to put uri with imageChooser's intent. Like this;
private void showCamera() {
try {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DCIM");
if (!file.exists()) {
file.mkdirs();
}
File localFile2 = new File(file + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
imageUri = Uri.fromFile(localFile2);
Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
cameraIntent.setClipData(ClipData.newRawUri(null, Uri.fromFile(localFile2)));
}
startActivityForResult(cameraIntent, REQUEST_CAMERA);
} catch (Exception localException) {
Toast.makeText(ActivityAddMemory.this, "Exception:" + localException, Toast.LENGTH_SHORT).show();
}
}
On selecting from gallery, complete data is returned with intent. You can use uri by accessing intent.getData() or thumbnail Bitmap using intent.getExtras().get("data"). Don't use imageUri that you passed with that intent.
On capturing from camera, in some devices intent is not null, but it's data is null. And in some devices, intent is null. Check both in onActivityResult.
Uri uri;
if (intent == null || intent.getData() == null) {
uri = this.imageUri;
} else {
uri = intent.getData();
}
Use this uri to display/upload your image.
so this was working lovely till yesterday when I upgraded my phone to 5.0.0 and tested the application out in a 5.0.0 emulator. Basically the purpose is to allow the user to take a photo, return it, open it to allow cropping then return it and set it as an imageview.
Everything worked fine before but now the intent in onActivityResult is null.
Here's code:
public void takeDisplayPicture(View view) {
final String TAKE_DISPLAY_PICTURE = "Take Display Picture";
Log.d(TAKE_DISPLAY_PICTURE, "Clicked");
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA_CAPTURE);
} catch (ActivityNotFoundException e) {
String msg = "Your device doesn't support a camera!";
Toast toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
toast.show();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final String RETURN_DISPLAY_PICTURE = "Return Display Picture";
Log.d(RETURN_DISPLAY_PICTURE, "Returned");
if (resultCode == RESULT_OK && requestCode == CAMERA_CAPTURE) {
picUri = data.getData();
performCrop(picUri);
} else if (requestCode == PIC_CROP) {
Bundle extras = data.getExtras();
bitmap = extras.getParcelable("data");
displayPicture.setImageBitmap(bitmap);
}
}
private void performCrop(Uri picUri) {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("outputX", 256);
cropIntent.putExtra("outputY", 256);
cropIntent.putExtra("return-data", true);
startActivityForResult(cropIntent, PIC_CROP);
} catch (ActivityNotFoundException e) {
String msg = "Your device doesn't support the crop action!";
Toast toast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
toast.show();
}
}
First, Android does not have a CROP Intent.
With respect to the null Uri, it is supposed to be null. Quoting the ACTION_IMAGE_CAPTURE documentation:
The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field.
You do not have EXTRA_OUTPUT, and so you are supposed to get your image via the poorly-documented (Bitmap)data.getExtras().get("data");.