I have a custom camera app and I want to pass the captured photo into another activity where I can add other icons (emoticons) over it.
How can i pass the captured photo to another activity?
You could pass the photo's URI via an intent. Assuming you call your camera with startActivityForResult(). In your camera activity:
Intent data = new Intent();
data.putExtra(MediaStore.EXTRA_OUTPUT, imageFilename);
setResult(Activity.RESULT_OK, data);
finish();
Then in your emoticon activity:
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && data.hasExtra(MediaStore.EXTRA_OUTPUT)) {
File imageFile = new File(data.getStringExtra(MediaStore.EXTRA_OUTPUT));
// Bitmap here, do whatever you need
Bitmap bitmap = readBitmapFromFile(imageFile.getName());
}
}
public static Bitmap readBitmapFromFile(#NotNull String filename) {
File file = new File(filename);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = false;
bmOptions.inPreferredConfig = Bitmap.Config.RGB_565;
bmOptions.inSampleSize = 1;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), bmOptions);
return bitmap;
}
Related
I am trying to get the image I am getting back at onActivityResult after picking an image at ACTION_GET_CONTENT system intent. I am using the doc's 'setPic()' method in order to reduce the image size but for some reason I get nothing when using the method. Here are my Intent, onActivityResulty and setPic() methods -
private void requestPickingPhoto() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, PICK_VIDEO_REQUEST_CODE);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_VIDEO_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri originalDataUri = data.getData();
cachedLocalImageUri = originalDataUri;
Timber.d("Receive image from: %s", originalDataUri);
mImageSent.setImageURI(cachedLocalImageUri);
setPic(originalDataUri.toString(), mImageSent);
}
}
private void setPic(String imagePath, ImageView destination) {
int targetW = destination.getWidth();
int targetH = destination.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = (int) Math.sqrt(Math.min(photoW/targetW, photoH/targetH));
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, bmOptions);
destination.setImageBitmap(bitmap);
}
my goal is to use the Uri I am getting back from the intent in order to reduce the image resolution dramaticly so I can use it for firebase cloud messaging rich notification which is size limited.
originalDataUri.toString() will not give you the file path.
Therefore you can't BitmapFactory.decodeFile(imagePath, bmOptions);.
Instead you can use BitmapFactory.decodeStream(InputStream is), once you open a stream from Uri:
Change parameter String imagePath of your setPic method to Uri uri, then instead of
BitmapFactory.decodeFile(imagePath, bmOptions);
do this:
InputStream is = context.getContentResolver().openInputStream(uri);
BitmapFactory.decodeStream(is, null, bmOptions);
And the same in the end of the method: instead of
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, bmOptions);
do
Bitmap bitmap = BitmapFactory.decodeStream(is, null, bmOptions);
Note, you need a valid Context for that.
I am working with capturing an image and then show it on my ImageView in my fragment. I searched this through web and still I cannot make it.
Below is what I am doing.
btnCaptureImg.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, 1888);
}
});
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.e("LOG", ""+requestCode);
if (requestCode == 1888 && resultCode == Activity.RESULT_OK) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(photo);
}
super.onActivityResult(requestCode, resultCode, data);
}
The Logcat says 1888 only but the imageView did not load the image.
I also tried this
btnCaptureImg.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
File folder = new File(Environment.getExternalStorageDirectory().toString()+"/ImagesFolder/");
folder.mkdirs();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
resultingFile = new File(folder.toString() + "/image.jpg");
Uri uriSavedImage=Uri.fromFile(resultingFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(cameraIntent, 1888);
}
});
But it throws exception:
E/AndroidRuntime(4824): java.lang.RuntimeException: Unable to resume activity {com.myapp.android/com.myapp.android.MyHomeActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=264032, result=-1, data=null} to activity {com.myapp.android/com.myapp.android.MyHomeActivity}: java.lang.NullPointerException
E/AndroidRuntime(4824): at com.myapp.android.MyFragment.onActivityResult(MyFragment.java:300)
Try putting
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, your_image_uri);
before this
startActivityForResult(cameraIntent, 1888);
I'm sorry mate but I can't seem to understand why it's giving that exception. Try this approach, it works for me.
Define the file globally and inside onActivityResult
if (requestCode == 1888 && resultCode == Activity.RESULT_OK) {
Bitmap photo = Media.getBitmap(getActivity().getContentResolver(), Uri.fromFile(resultingFile));
//Bitmap photo = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(photo);
}
Check if your onActicityResult is beeing called. If not check:
onActivityResult is not being called in Fragment
First, in the fragment starts the intent to capture the image:
private void startIntentImageCapture() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile("imageName.jpg", ".jpg", storageDir);
path = Uri.fromFile(image);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, path);
getActivity().startActivityForResult(cameraIntent, CAPTURE_IMAGE_REQUEST_CODE);
} catch (IOException e) {
e.printStackTrace();
}
}
path variable, must be an public static Uri instance. And another public static Integer for the request code: public static final Integer CAPTURE_IMAGE_REQUEST_CODE = 100;
Then in the Activity, read this path and decode the image:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == YourFragment.CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Bitmap imageBitmap = decodeFile(YourFragment.path);
//do something with your photo
}
}
}
I'm sure this is not the best and cleaner method but it works for me. Hope it helps!
EDIT
I forgot the code to decode the image.
public Bitmap decodeFile(Uri uriFile) throws OutOfMemoryError {
String filePath = uriFile.getPath();
BitmapFactory.Options bmOptions;
Bitmap imageBitmap;
try {
imageBitmap = BitmapFactory.decodeFile(filePath);
} catch (OutOfMemoryError e) {
bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 4;
bmOptions.inPurgeable = true;
imageBitmap = BitmapFactory.decodeFile(filePath, bmOptions);
}
return imageBitmap;
}
The bmOptions ensure that OutOfMemoryError doesn't occurs.
I'm using these codes to capture and store an image on a button click.
takePhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
destination = new File(Environment
.getExternalStorageDirectory(),
preferences.getSelectedItem().getItemNo() + "_"
+ preferences.getSelectedItem().getChasisNo() + "_up");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(destination));
startActivityForResult(intent, TAKE_PHOTO_CODE);
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
FileInputStream in;
try {
in = new FileInputStream(destination);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 10;
imgPath = destination.getAbsolutePath();
// Bitmap bmp = BitmapFactory.decodeStream(in, null, options);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("Image saved", "Image saved at " + imgPath);
upItem.setUpPhotoURL(String.valueOf(imgPath));
isPhotoAttached = true;
}
}
But when I capture the photo and try to confirm it, app does nothing. Cancelling and retaking options work perfectly but confirming the taken image doesn't do anything. Can anyone point me where the problem lies here?
added this permission in your manifest file
<uses-feature android:name="android.hardware.camera" />
.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PHOTO_CODE && resultCode == RESULT_OK) {
String[] projection = { MediaStore.Images.Media.DATA};
#SuppressWarnings("deprecation")
Cursor cursor = managedQuery(mCapturedImageURI, projection, null, null, null);
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String capturedImageFilePath = cursor.getString(column_index_data);
Toast.makeText(this, capturedImageFilePath, Toast.LENGTH_SHORT).show();
}
Try this
String mCurrentPhotoPath = destination.getAbsolutePath();
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TAKE_PHOTO_CODE: {
if (resultCode == RESULT_OK) {
if (mCurrentPhotoPath != null) {
getBitmap(mCurrentPhotoPath);
}
}
break;
}
default:
break;
}
}
private Bitmap getBitmap(String mCurrentPhotoPath) {
/* There isn't enough memory to open up more than a couple camera photos */
/* So pre-scale the target bitmap into which the file is decoded */
/* Get the size of the ImageView */
int targetW = imageView.getMeasuredWidth();
int targetH = imageView.getMeasuredHeight();
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
Bitmap oribitmap = BitmapFactory.decodeFile(mCurrentPhotoPath,
bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = 3;
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
/* Decode the JPEG file into a Bitmap */
return oribitmap = BitmapFactory.decodeFile(mCurrentPhotoPath,
bmOptions);
}
This permission in your manifest file
<uses-feature android:name="android.hardware.camera" />
I think this is not working because the name of the image is too big. When I changed this
destination = new File(Environment.getExternalStorageDirectory(),
preferences.getSelectedItem().getItemNo() + "_"
+ preferences.getSelectedItem().getChasisNo() + "_up");
to this
destination = new File(Environment.getExternalStorageDirectory(),
preferences.getSelectedItem().getChasisNo() + ".jpg");
I'm not sure if there's such a thing as the image name being too big, but this change is working for me
I am doing an android app, in which I have a functionality that, I need to open camera and take a picture. After taking picture onActivityResult is not called. my screen remains only in camera state.
My code:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File mediaFile = new File(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI.getPath());
Uri imageUri = Uri.fromFile(mediaFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, 1);
onActivityResult code
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && !data.toString().equalsIgnoreCase("Intent { }"))
switch (requestCode) {
case 1:
Log.i("StartUpActivity", "Photo Captured");
Uri uri = data.getData();
String imgPath = getRealPathFromURI(uri);
bitmap = (Bitmap) data.getExtras().get("data");
MediaStore.Images.Media.insertImage(getContentResolver(),
bitmap, null, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
img1.setImageBitmap(bitmap);
}
}
onActivityResult is probably called, but the statements inside your if statement and switch/case statements are not being executed, because they are never reached.
The code below includes two methods takePhoto and onActivityResult, is very short and works perfectly. Take a look at it, it probably will help you!
public void takePhoto(View v) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
photo = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(photo);
}
}
You can run your application in debug mode, after putting a breakpoint in onActivityResult method,
if it's stopping there after getting from the Camera then it's being called successfully.
and you could just change the if statement you're using making your code like this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null && resultCode = RESULT_OK)
switch (requestCode) {
case 1:
Log.i("StartUpActivity", "Photo Captured");
Uri uri = data.getData();
String imgPath = getRealPathFromURI(uri);
bitmap = (Bitmap) data.getExtras().get("data");
MediaStore.Images.Media.insertImage(getContentResolver(),
bitmap, null, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
img1.setImageBitmap(bitmap);
}
}
and note that it is more recommended to using final ints as the request code instead of rewriting them everytime they're needed
like :
private final int START_CAMERA_REQUEST_CODE = 1;
I think this may be help you
Follow Below Code step by step and compare with your code to avoid null exception
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);
1 OnActivity Result
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 1)
onCaptureImageResult(data);
}
}
2
onCaptureImageResult
public void onCaptureImageResult(Intent data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
Uri tempUri = getImageUri(getApplicationContext(), thumbnail); // call getImageUri
File finalFile = new File(getRealPathFromURI(tempUri));
file_path = finalFile.getPath().toString(); // your file path
imgview.setImageBitmap(thumbnail);
// this code will get your capture image bitmap}
3 getImageUri
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null); // your capture image URL code
return Uri.parse(path);
}
Using this code your screen will not remain more on camera state it will finish and image will be load as well you get image URL.
Bitmap mBitmap = BitmapFactory.decodeFile(imgPath);
pass Image path which you create from URI.
Probably, your activity is reloaded after camera is finished, but your code is not prepared to such situation.
See Android startCamera gives me null Intent and ... does it destroy my global variable?.
I think onActivity is called but it doesn't go into the if condition
Check only for null in if condition:
if (data != null )
switch (requestCode) {
case 1:
Log.i("StartUpActivity", "Photo Captured");
Uri uri = data.getData();
String imgPath = getRealPathFromURI(uri);
bitmap = (Bitmap) data.getExtras().get("data");
MediaStore.Images.Media.insertImage(getContentResolver(),
bitmap, null, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
img1.setImageBitmap(bitmap);
}
From where you are calling startActivityForResult(intent, 1),
and where you Overriding onActivityResult() ?
I mean if you call startActivityForResult() from Frgment then you should override onActivityResult() in fragment it self, same applies to Activity also.
Just simple as the title, files opened with BitmapFactory.decodeFile have wrong orientation when it is displayed on the ImageView. The image its captured from the camera and saved on a tmp file so if the device has the bug that returns data.getData() null I have at least a reference to the file.
This just start the camera activity and capture the image file
private void startCamera() {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (hasImageCaptureBug()) {
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Constants.TMPFILE_PATH)));
} else {
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST) {
if (resultCode == RESULT_OK) {
Uri uri = null;
if (hasImageCaptureBug()) {
File f = new File(Constants.TMPFILE_PATH);
try {
uri = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), f.getAbsolutePath(), null, null));
} catch (FileNotFoundException e) {
}
} else {
uri = data.getData();
}
imageFilePath = Image.getPath(this, uri);
if (Image.exists(imageFilePath)) {
ImageView image = (ImageView) findViewById(R.id.thumbnail);
int targetW = (int) getResources().getDimension(R.dimen.thumbnail_screen_width);
int degrees = (int) Image.getRotation(this, uri);
Bitmap bmp = Image.resize(imageFilePath, targetW);
bmp = Image.rotate(bmp, degrees);
image.setAdjustViewBounds(true);
image.setImageBitmap(bmp);
}
}
}
}
And this file resizes the image
public class Image {
public static Bitmap resize(String pathName, int targetW) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(pathName, opts);
int photoW = opts.outWidth;
int photoH = opts.outHeight;
int targetH = Math.round((photoH * targetW) / photoW);
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
opts.inJustDecodeBounds = false;
opts.inSampleSize = scaleFactor;
opts.inPurgeable = true;
bmp = BitmapFactory.decodeFile(pathName, opts);
return bmp;
}
}
Tryed to get the ExifOrientation but always its 0 because the file itself its correctly oriented just when I load it the file is displayed with the wrong orientation.
Regards
seems that my issue to preview the image was the Constants.TMPFILE_PATH, the image was not saved there, I just use this fix Display the latest picture taken in the image view layout in android!, but the issue persist if I post it to the server... I'll check this as answered and open a new question to this...
Edited
To solve this issue just refactor the new image and then upload it to the server, because the raw data of the file itself has his exif orientation was wrong.