I'm trying to capture an image, but after capturing and approving, onActivityResult(int requestCode, int resultCode, Intent data) the data is always null .
This is how I call the camera:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, getImageUri());
startActivityForResult(intent, Consts.ACTION_JOURNEY_CAPTURE_PHOTO_PATH);
Method getImageUri():
private Uri getImageUri() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "IMG_" + timeStamp + "_";
File albumF = helpers.getAlbumDir(getString(R.string.album_name));
File file = new File(albumF, imageFileName);
Uri imgUri = Uri.fromFile(file);
return imgUri;
}
On manifest I have :
<uses-feature android:name="android.hardware.camera" />
What am I doing wrong?
The image is stored at the path that you get with the method getImageUri(). You must keep that path and inside onActivityResult() do the following:
if (resultCode == RESULT_OK) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(photoPath, options);
Bitmap b = BitmapFactory.decodeFile(photoPath, options);
}
If you want to resize the image, you can set the inSampleSize of your BitmapFactory.Options, this method will be useful to calculate the inSampleSize:
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
Related
Below is the code I use to read my image file when I save my image file using FileProvider:
public static Bitmap readBitmapFromIntentReturn(Context context, Intent intentReturn, Uri uri) {
try {
AssetFileDescriptor fileDescriptor = null;
fileDescriptor = context.getContentResolver().openAssetFileDescriptor(uri, "r");
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
options.inSampleSize = SystemFunctions.calculateInSampleSize(options);
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options);
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
2. Method use to resize the image before I upload it or other, not sure the size is resize correctly or not:
public static int calculateInSampleSize(BitmapFactory.Options options) {
final int reqHeight = 360;
final int reqWidth = 360;
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
Log.d("TestSampleSize", "TestSampleSize : " + String.valueOf(inSampleSize));
return inSampleSize;
}
I'm attempting to scale down a bitmap to load a smaller version into memory. I'm pretty much following Google's example (search Loading Large Bitmaps Efficiently), except that I'm loading from the image gallery instead of a resource. But I seem to be getting back a null bitmap after calculating dimensions. Here's my code:
/** OnActivityResult Method **/
final Uri imageUri = data.getData();
final InputStream imageStream = getActivity().getContentResolver().openInputStream(imageUri);
Bitmap bitmapToLoad = Util.decodeSampledBitmapFromResource(imageStream, 500, 500); // bitmapToLoad is null.
mIvScreenshot.setImageBitmap(bitmapToLoad);
/**Helper Methods **/
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(InputStream is,
int reqWidth, int reqHeight) {
Rect rect = new Rect();
// First decode with inJustDecodeBounds = true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, rect, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(is, rect, options);
}
Can anyone catch what I'm doing wrong?
I managed to get it working. Thanks to Biraj Zalavadia (How to reduce an Image file size before uploading to a server) for the scaling logic, and the cursor code here (How to return workable filepath?). Here is my onActivityResult():
try {
final Uri imageUri = data.getData();
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor cursor = getActivity().getContentResolver().query(imageUri, filePath, null, null, null);
cursor.moveToFirst();
String imagePath = cursor.getString(cursor.getColumnIndex(filePath[0]));
Uri newUri = Uri.parse(ScalingUtilities.scaleFileAndSaveToTmp(imagePath, 500, 500));
final Bitmap selectedImage = BitmapFactory.decodeFile(newUri.getEncodedPath());
mIvScreenshot.setImageBitmap(selectedImage);
} catch (Exception e) {
// Handle
}
What i'm doing/trying to do, is.
1. Take a photo
2. Save it
3. Load/display it into a Bitmap
Opening the Built in camera application:
public void openCamera() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory()+ File.separator + "image.jpg");
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
onActivityResult:
protected void onActivityResult(int requestCode, int resultCode, Intent data){
//Check that request code matches ours:
if (requestCode == REQUEST_IMAGE_CAPTURE){
//Get our saved file into a bitmap object:
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image.jpg");
Bitmap image = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);
}
}
decodeSamoleBitmapFromFile:
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight)
{ // BEST QUALITY MATCH
//First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize, Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > reqHeight)
{
inSampleSize = Math.round((float)height / (float)reqHeight);
}
int expectedWidth = width / inSampleSize;
if (expectedWidth > reqWidth)
{
//if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
inSampleSize = Math.round((float)width / (float)reqWidth);
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
I was hoping for it to load it into a bitmap. If anyone could point me in the right direction that would be very helpful!
In order to display a Bitmap, you'll have to use an ImageView. Once you have both the bitmap and the reference to your ImageView, call ImageView.setImageBitmap(Bitmap) to display your bitmap.
I am using library https://github.com/jdamcd/android-crop and not being able to get the cropped image i dont know why below is some code that i am following from documentation
_Profile_Image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE_FROM_GALARY);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent result) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_PICTURE_FROM_GALARY) {
beginCrop(result.getData());
}
}
if (requestCode == Crop.REQUEST_PICK && resultCode == Activity.RESULT_OK) {
beginCrop(result.getData());
} else if (requestCode == Crop.REQUEST_CROP) {
handleCrop(resultCode, result);
}
}
private void beginCrop(Uri source) {
Uri outputUri = Uri.fromFile(new File(getActivity().getCacheDir(), "cropped"));
new Crop(source).output(outputUri).asSquare().start(getActivity());
}
private void handleCrop(int resultCode, Intent result) {
if (resultCode == Activity.RESULT_OK) {
_Profile_Image.setImageURI(Crop.getOutput(result));
} else if (resultCode == Crop.RESULT_ERROR) {
Toast.makeText(getActivity(), Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
}
}
i am able to open the corp activity and it also crops the image and showing saving picture, but the problem is that after cropping image it is not coming in onActivityResult so that i can handle the crop image.
I Dont know what i am doing wrong in the code , I am just following the documentation
Help will be Appreciated Thanks.
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class ImageResizer {
public static Bitmap decodeSampledBitmapFromFile(String filename,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options
options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filename, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// BEGIN_INCLUDE (calculate_sample_size)
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
// This offers some additional logic in case the image has a strange
// aspect ratio. For example, a panorama may have a much larger
// width than height. In these cases the total pixels might still
// end up being too large to fit comfortably in memory, so we should
// be more aggressive with sample down the image (=larger inSampleSize).
long totalPixels = width * height / inSampleSize;
// Anything more than 2x the requested pixels we'll sample down further
final long totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels > totalReqPixelsCap) {
inSampleSize *= 2;
totalPixels /= 2;
}
}
return inSampleSize;
// END_INCLUDE (calculate_sample_size)
}
}
Hope this help :)
In the android app that I am making a user takes a photo which I want to display him later in few activities. I've come up to "out of memory error" while displaying currently taken photo in an image view, so I decided to use code from http://developer.android.com/training/displaying-bitmaps/load-bitmap.html to do it efficiently. Here are methods that I'm using:
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
and
public static Bitmap decodeSampledBitmap(Uri mUri, int reqWidth, int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mUri.getPath(), options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(mUri.getPath, options);
};
I let the user take photo by the method:
static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent(){
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(takePictureIntent.resolveActivity(getPackageManager()) != null){
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
And then receive taken picture info:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK){
Uri imageUri = null;
if(data != null){
imageUri = data.getData();
}
ImageView imageView = (ImageView)findViewById(R.id.new_photo);
imageView.setImageBitmap(decodeSampledBitmap(imageUri, imageView.getWidth(), imageView.getHeight()));
}
}
My app breaks and I get info: "File not found or no such directory".
I checked what does the imageUri.getPath() give and in my case its:
"/external/images/media/1777" (which seems quite strange to me because I'm not using SD card)
and the taken photo is actually saved in "/storage/emulated/0/DCIM/100ANDRO/DSC_0052.JPG". Do you have any ideas what am I doing wrong?
Intent Extra Max limit is 1MB approx till gingerbread..
I found a magic number 86389 in JellyBean if you send above this it will throw memory out of exception..
Solution : Pass Image Uri, dont pass complete bitmap object
Use following code just before startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, getImageUri());
Where getImageUri() is
private Uri getImageUri() {
// Store image in dcim
File myDir = new File(Environment.getExternalStorageDirectory()
+ "/My_App");
if(!myDir.exists())
myDir.mkdir();
File file = new File(myDir, "MyImage.png");
Uri imgUri = Uri.fromFile(file);
return imgUri;
}
Read up Android official docs regarding this for further clarification.