I'm trying to create simple Contact app. Naturally there is Contact class with member variable mCurrentPhotoPath. An activity which is responsible for creating Contact, has an option to pick image from Gallery in the following way:
final Intent pickImage = new Intent(Intent.ACTION_GET_CONTENT);
pickImage.setType("image/*")
/*some code...*/
galleryButton.setOnClickListener((View v) -> {
startActivityForResult(pickImage, REQUEST_GALLERY_PHOTO);
});
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_GALLERY_PHOTO && resultCode == RESULT_OK){
photoTaken = true;
Uri selectedImage = data.getData();
Log.i("path", selectedImage.getPath()) //prints out: /document/image:292562
mPhotoView.setImageURI(selectedImage);
I am able to display selected image in ImageView (mPhotoView).
However, when I try to set Intent in different way, I get full path, but I cannot recreate file from that path and I get FileNotFoundException.
final Intent pickImage = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_GALLERY_PHOTO && resultCode == RESULT_OK){
photoTaken = true;
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
if (selectedImage != null) {
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
Log.i.("TAG", picturePath); //I get, /storage/emulated/0/Pictures/Viber/IMG-bbd54c96cc971a1700f92205937014c8-V.jpg
mPhotoFile = new File(picturePath);
cursor.close();
updatePhotoView(); //This method recreates image based on exact file path and witdh & height of ImageView where the picture is going to be placed;
}
}
}
Here is updatePhotoView()
private void updatePhotoView(int imageWidth, int imageHeight) {
if (mPhotoFile == null || !mPhotoFile.exists()) {
mPhotoView.setImageDrawable(null);
} else {
Bitmap bitmap = PictureUtils.getScaledBitmap(mPhotoFile.getPath(),imageWidth, imageHeight); // imageWidth & imageHeight are member variables of actiivty...
mPhotoView.setImageBitmap(bitmap);
}
}
I'm pretty sure this function works, because when I implemented option to take picture from camera (I created file with getExternalFilesDir(), and in any other activity when I passed string value of mCurrentPhotoPath, getScaledBitmap() managed to recreate image).
Here is getScaledBitmap():
public static Bitmap getScaledBitmap(String path, int destWidth, int destHeight) {
// Read in the dimensions of the image on disk
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
float srcWidth = options.outWidth;
float srcHeight = options.outHeight;
// Figure out how much to scale down by
int inSampleSize = 1;
if (srcHeight > destHeight || srcWidth > destWidth) {
if (srcWidth > srcHeight) {
inSampleSize = Math.round(srcHeight / destHeight);
} else {
inSampleSize = Math.round(srcWidth / destWidth);
}
}
options = new BitmapFactory.Options();
options.inSampleSize = inSampleSize;
// Read in and create final bitmap
return BitmapFactory.decodeFile(path, options);
}
Just if anyone stumbles on similar problem. I solved my problem of getting images by using Glide library. Look it up, bunch of tutorials. I guess that this load function is doing heavy lifting in the background. Great thing! Here is how code looks like:
Glide.with(context)
.load(imageFilePath)
.apply(new RequestOptions().centerCrop())
.override(imageView.getWidth(), imageView.getHeight())
.into(imageView);
Related
I am trying to choose an image for registration. When clicking the ImageView, the user will be given a choice between taking a picture or choosing from his/her gallery. When the user chooses the gallery option, it will display the selected image. When the user chooses the camera option, the ImageView does not display the image. Below is my code for the OnActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent imgdata) {
super.onActivityResult(requestCode, resultCode, imgdata);
if (requestCode == SELECT_IMAGE && resultCode == RESULT_OK && imgdata != null) {
selectedimage = imgdata.getData();
try {
InputStream inputStream = getContentResolver().openInputStream(selectedimage);
Bitmap yourselectedimage = BitmapFactory.decodeStream(inputStream);
imgchild.setImageBitmap(yourselectedimage);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Hello", Toast.LENGTH_SHORT).show();
}
}
if (requestCode == CAPTURE_IMAGE && resultCode == RESULT_OK && imgdata != null) {
camImg =(Bitmap) imgdata.getExtras().get("img");
try {
imgchild.setImageBitmap(camImg);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Hello", Toast.LENGTH_SHORT).show();
}
}
}
The ImageView should display the taken picture from the camera.
I think it should be like this
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
By reading your code, I think it's highly likely that camImg is null because the way you extract bitmap from Intent is incorrect.
Bitmap implements Parcelable, so you need to extract it like this:
camImg = (Bitmap) imgdata.getParcelableExtra("img");
I hope this will work for you.
Set image like this
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(photo);
// CALL THIS METHOD TO GET THE ACTUAL PATH
Uri tempUri = getImageUri(getApplicationContext(), photo);
File finalFile = new File(getRealPathFromURI(tempUri));
Log.e("path", finalFile.getAbsolutePath());
To get image path where it is stored
public String getRealPathFromURI(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
I faced same issue with Android Marshmallow, in my case, it is happening due to large bitmap so I figured out with the following code by resizing bitmap
final int maxSize = 960;
int outWidth;
int outHeight;
int inWidth = CameraActivity.bitmap.getWidth();
int inHeight = CameraActivity.bitmap.getHeight();
if(inWidth > inHeight){
outWidth = maxSize;
outHeight = (inHeight * maxSize) / inWidth;
} else {
outHeight = maxSize;
outWidth = (inWidth * maxSize) / inHeight;
}
iv_captured_image.setImageBitmap(Bitmap.createScaledBitmap(CameraActivity.bitmap, outWidth, outHeight, false));
I was using this code to allow the user to choose an image from a gallery app and to get that image afterwards.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == getActivity().RESULT_OK) {
if (requestCode == REQUEST_CAMERA) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
mImg.setImageBitmap(photo);
} else if (requestCode == SELECT_FILE) {
Uri selectedImageUri = data.getData();
String[] projection = {MediaStore.MediaColumns.DATA};
CursorLoader cursorLoader = new CursorLoader(getActivity(), selectedImageUri, projection, null, null,
null);
Cursor cursor = cursorLoader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
cursor.moveToFirst();
String selectedImagePath = cursor.getString(column_index);
Bitmap bm;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(selectedImagePath, options);
final int REQUIRED_SIZE = 200;
int scale = 1;
while (options.outWidth / scale / 2 >= REQUIRED_SIZE
&& options.outHeight / scale / 2 >= REQUIRED_SIZE)
scale *= 2;
options.inSampleSize = scale;
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(selectedImagePath, options);
mImg.setImageBitmap(bm);
mImg.setAlpha(1);
}
}
}
But in this answer here I was told that this code wont work in most android devices. Can I know why? And what is the best way to get an image chosen by the user.
I posted this in a separate question because it might be interesting.
By using bitmap, your image may looked blurry. If the image size too large, it will be a problem when you want to upload or retrieved them to(from) server. So uri is better than bitmap.
You may try below code and you will see the difference between bitmap and uri
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RESULT_LOAD_IMAGE:
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK & null != data) {
selectedImage = data.getData();
imageView.setImageURI(selectedImage);
}
else
{
imageView.setImageResource(R.mipmap.no_image);
}
break;
case REQUEST_IMAGE_CAPTURE:
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
try {
selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
imageView.setImageURI(null);
imageView.setImageURI(imageUri);
} catch (Exception e) {
Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT)
.show();
Log.e("Camera", e.toString());
}
Log.e("A", "AAA");
}
}
}
How can I allow the user to choose between capturing an image or selecting it from the gallery, and I want to know the type of the photo afterwards (PNG/JPG).
I'm using this code but it is not working well.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == getActivity().RESULT_OK) {
if (requestCode == REQUEST_CAMERA) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
mImg.setImageBitmap(photo);
} else if (requestCode == SELECT_FILE) {
Uri selectedImageUri = data.getData();
String[] projection = {MediaStore.MediaColumns.DATA};
CursorLoader cursorLoader = new CursorLoader(getActivity(), selectedImageUri, projection, null, null,
null);
Cursor cursor = cursorLoader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
cursor.moveToFirst();
String selectedImagePath = cursor.getString(column_index);
Bitmap bm;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(selectedImagePath, options);
final int REQUIRED_SIZE = 200;
int scale = 1;
while (options.outWidth / scale / 2 >= REQUIRED_SIZE
&& options.outHeight / scale / 2 >= REQUIRED_SIZE)
scale *= 2;
options.inSampleSize = scale;
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(selectedImagePath, options);
mImg.setImageBitmap(bm);
mImg.setAlpha(1);
}
}
}
I want to know the type of the photo afterwards (PNG/JPG)
Call getType() on a ContentResolver, passing in the Uri.
I'm using this code but it is not working well.
Delete most of what you have, as your selectedImagePath code will fail on most Android devices and you are decoding the bitmap on the main application thread. Use an image-loading library like Picasso to handle the image loading for you, asynchronous, including the scaling. Picasso can use the Uri directly without any of the flawed selectedImagePath stuff. Then, all you need is the getType() call to get the MIME type of the image. Your entire requestCode == SELECT_FILE block will be replaced by 2-3 lines of code.
You have to install Apache Commons Io
Use FilenameUtils.getExtention() from this lib
String ext = FilenameUtils.getExtension("/path/to/file/foo.txt");
i think this will help you
So last night i thought i had my app working, however, this morning the gremlins have invaded and have now made a function of my app not work correctly.
Basically, a button allows the user to take a photo, and have that photo displayed in an Imageview, then attach the image to an email.. It lets me take the photo, and it is still present as an attachment, but the preview in the image view is completely empty.
Can anybody see what is going on?
Hoon_Image = (ImageView) findViewById(R.id.CapturedImage);
button_take_photo = (Button)findViewById(R.id.btn_take_photo);
button_take_photo.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
try {
f = createImageFile();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(cameraIntent, CAMERA_REQUEST);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
public File getAlbumDir()
{
File storageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
),
"BAC/"
);
// Create directories if needed
if (!storageDir.exists()) {
storageDir.mkdirs();
}
return storageDir;
}
private File createImageFile() throws IOException {
// Create an image file name
String imageFileName =getAlbumDir().toString() +"/image.jpg";
File image = new File(imageFileName);
return image;
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if(requestCode == CAMERA_REQUEST ){
Bitmap photo = BitmapFactory.decodeFile(f.getAbsolutePath());
Hoon_Image.setImageBitmap(photo);
}
}
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
//OI FILE Manager
filemanagerstring = selectedImageUri.getPath();
//MEDIA GALLERY
selectedImagePath = getPath(selectedImageUri);
//DEBUG PURPOSE - you can delete this if you want
if(selectedImagePath!=null)
System.out.println(selectedImagePath);
else System.out.println("selectedImagePath is null");
if(filemanagerstring!=null)
System.out.println(filemanagerstring);
else System.out.println("filemanagerstring is null");
//NOW WE HAVE OUR WANTED STRING
if(selectedImagePath!=null)
System.out.println("selectedImagePath is the right one for you!");
else
System.out.println("filemanagerstring is the right one for you!");
}
Bitmap photo = BitmapFactory.decodeFile(selectedImagePath);
Hoon_Image.setImageBitmap(photo);
Photo_Selected = 1;
}
}
What I've done for the image to be shown in the ImageView in Android is to use a method decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) that decodes the File object with a required width and height. Below is a sample code.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_OK) {
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + "image.jpg");
bitmap = decodeSampledBitmapFromFile(file.getAbsolutePath(),
600, 450);
imageView.setImageBitmap(bitmap);
}
}
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth,
int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
// Query bitmap without allocating memory
options.inJustDecodeBounds = true;
// decode file from path
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
// decode according to configuration or according best match
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);
}
// if value is greater than 1,sub sample the original image
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
So i found to what i was doing wrong - derp moment coming right up.
this section of code:
if (resultCode == RESULT_OK) {
if(requestCode == CAMERA_REQUEST ){
it was just looking of ok result (which happened both for selecting a photo and taking a photo successfully) rather than first looking for the RequestCode.
rearranging the code to this worked:
if(requestCode == CAMERA_REQUEST ) {
if (resultCode == RESULT_OK){
Bitmap photo = BitmapFactory.decodeFile(f.getAbsolutePath());
Hoon_Image.setImageBitmap(photo);
I have an app, which has a button to select a photo from your gallery and it works fine and after selecting the image my app show came back to the activity and shows the image in an image View.
Every is working fine but sometimes ,when i select some particular images the preview is not showing. I have also tried to compress the image still its not working
My code is below..
In onCreate()
galeryBtn=(Button)findViewById(R.id.buttonGallery);
galeryBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}
});
In onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
// String picturePath contains the path of selected Image
// Show the Selected Image on ImageView
ImageView imageView = (ImageView) findViewById(R.id.imgView);
imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
}
Try like this
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
switch (requestCode) {
case RESULT_LOAD_IMAGE:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = intent.getData();
try {
Bitmap bitmapImage =decodeBitmap(selectedImage );
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Show the Selected Image on ImageView
ImageView imageView = (ImageView) findViewById(R.id.imgView);
imageView.setImageBitmap(bitmapImage);
}
And
public Bitmap decodeBitmap(Uri selectedImage) throws FileNotFoundException {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);
final int REQUIRED_SIZE = 100;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) {
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);
}
I run into similar problems like getting cursor uri from resource, open stream, set bitmap etc. And it has bugs all the time.
So I searched libraries and found image-chooser-library library.
I bet you would like to try this project from image-chooser-library
It is very easy to use and solves all those nitty gritty problems for you, like images from picasa etc.
Hopefully it is useful for you.
The way you're trying to load a bitmap in onActivityResult() is not absolutely right. Sometimes you will not be able to open an image and your application can crash. You'd better use code like this:
Uri imageUri = data.getData();
InputStream imageStream = null;
try {
imageStream = getContentResolver().openInputStream(imageUri);
ImageView imageView = (ImageView) findViewById(R.id.imgView);
imageView.setImageBitmap(BitmapFactory.decodeStream(imageStream));
} catch (FileNotFoundException e) {
// Handle the error
} finally {
if (imageStream != null) {
try {
imageStream.close();
} catch (IOException e) {
// Ignore the exception
}
}
}
Add this after imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath));
imageView.setImageURI(selectedImage);
It work for me.