How to get a Bitmap object from an Uri (if I succeed to store it in
/data/data/MYFOLDER/myimage.png or file///data/data/MYFOLDER/myimage.png) to use it in my application?
Does anyone have an idea on how to accomplish this?
Here's the correct way of doing it:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
Uri imageUri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
}
}
If you need to load very large images, the following code will load it in in tiles (avoiding large memory allocations):
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false);
Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null);
See the answer here
Here's the correct way of doing it, keeping tabs on memory usage as well:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK)
{
Uri imageUri = data.getData();
Bitmap bitmap = getThumbnail(imageUri);
}
}
public static Bitmap getThumbnail(Uri uri) throws FileNotFoundException, IOException{
InputStream input = this.getContentResolver().openInputStream(uri);
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;
onlyBoundsOptions.inDither=true;//optional
onlyBoundsOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//optional
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
input.close();
if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1)) {
return null;
}
int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight : onlyBoundsOptions.outWidth;
double ratio = (originalSize > THUMBNAIL_SIZE) ? (originalSize / THUMBNAIL_SIZE) : 1.0;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio);
bitmapOptions.inDither = true; //optional
bitmapOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//
input = this.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
return bitmap;
}
private static int getPowerOfTwoForSampleRatio(double ratio){
int k = Integer.highestOneBit((int)Math.floor(ratio));
if(k==0) return 1;
else return k;
}
The getBitmap() call from Mark Ingram's post also calls the decodeStream(), so you don't lose any functionality.
References:
Android: Get thumbnail of image on SD card, given Uri of original image
Handling large Bitmaps
It seems that MediaStore.Images.Media.getBitmap was deprecated in API 29. The recommended way is to use ImageDecoder.createSource which was added in API 28.
Here's how getting the bitmap would be done:
val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
ImageDecoder.decodeBitmap(ImageDecoder.createSource(requireContext().contentResolver, imageUri))
} else {
MediaStore.Images.Media.getBitmap(requireContext().contentResolver, imageUri)
}
IMPORTANT: ImageDecoder.decodeBitmap read EXIF orientation, Media.getBitmap doesn't
try
{
Bitmap bitmap = MediaStore.Images.Media.getBitmap(c.getContentResolver() , Uri.parse(paths));
}
catch (Exception e)
{
//handle exception
}
and yes path must be in a format of like this
file:///mnt/sdcard/filename.jpg
private void uriToBitmap(Uri selectedFileUri) {
try {
ParcelFileDescriptor parcelFileDescriptor =
getContentResolver().openFileDescriptor(selectedFileUri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
} catch (IOException e) {
e.printStackTrace();
}
}
This is the easiest solution:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
Uri imgUri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imgUri);
You can retrieve bitmap from uri like this
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
} catch (IOException e) {
e.printStackTrace();
}
private fun setImage(view: ImageView, uri: Uri) {
val stream = contentResolver.openInputStream(uri)
val bitmap = BitmapFactory.decodeStream(stream)
view.setImageBitmap(bitmap)
}
by using glide library you can get bitmap from uri,
almost in samsung devices image rotated when and we have to check rotation using exifinterface
but using glide no need to check rotation, image always correctly received.
in kotlin you can get bitmap as
CoroutineScope(Dispatchers.IO).launch {
var bitmap = Glide.with(context).asBitmap().load(imageUri).submit().get()//this is synchronous approach
}
I am using this dependency
api 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
Bitmap bitmap = null;
ContentResolver contentResolver = getContentResolver();
try {
if(Build.VERSION.SDK_INT < 28) {
bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri);
} else {
ImageDecoder.Source source = ImageDecoder.createSource(contentResolver, imageUri);
bitmap = ImageDecoder.decodeBitmap(source);
}
} catch (Exception e) {
e.printStackTrace();
}
Inset of getBitmap which is depricated now I use the following approach in Kotlin
PICK_IMAGE_REQUEST ->
data?.data?.let {
val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(it))
imageView.setImageBitmap(bitmap)
}
InputStream imageStream = null;
try {
imageStream = getContext().getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
ContentResolver cr = context.getContentResolver();
try (InputStream input = cr.openInputStream(url)) {
Bitmap bitmap = BitmapFactory.decodeStream(input);
}
Use startActivityForResult metod like below
startActivityForResult(new Intent(Intent.ACTION_PICK).setType("image/*"), PICK_IMAGE);
And you can get result like this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) {
return;
}
switch (requestCode) {
case PICK_IMAGE:
Uri imageUri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
I have try a lot of ways. this work for me perfectly.
If you choose pictrue from Gallery. You need to be ware of getting Uri from intent.clipdata or intent.data, because one of them may be null in different version.
private fun onChoosePicture(data: Intent?):Bitmap {
data?.let {
var fileUri:Uri? = null
data.clipData?.let {clip->
if(clip.itemCount>0){
fileUri = clip.getItemAt(0).uri
}
}
it.data?.let {uri->
fileUri = uri
}
return MediaStore.Images.Media.getBitmap(this.contentResolver, fileUri )
}
I don't see the right answer, so I'll put this extension here
fun Context.getBitmap(uri: Uri): Bitmap =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) ImageDecoder.decodeBitmap(ImageDecoder.createSource(this.contentResolver, uri))
else MediaStore.Images.Media.getBitmap(this.contentResolver, uri)
Example in code:
val bitmap = context.getBitmap(uri)
Tip: You can also update the extension for activity/fragment, so you don't
need to write the context at all. A little more synth sugar)
you can do this structure:
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case 0:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
Bundle extras = imageReturnedIntent.getExtras();
bitmap = extras.getParcelable("data");
}
break;
}
by this you can easily convert a uri to bitmap.
hope help u.
(KOTLIN)
So, as of April 7th, 2020 none of the above mentioned options worked, but here's what worked for me:
If you want to store the bitmap in a val and set an imageView with it, use this:
val bitmap = BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }
If you just want to set the bitmap to and imageView, use this:
BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }
* For getting bitmap from uri. Work for me perfectly.
public static Bitmap decodeUriToBitmap(Context mContext, Uri sendUri) {
Bitmap getBitmap = null;
try {
InputStream image_stream;
try {
image_stream = mContext.getContentResolver().openInputStream(sendUri);
getBitmap = BitmapFactory.decodeStream(image_stream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return getBitmap;
}
val bitmap = context.contentResolver.openInputStream(uri).use { data ->
BitmapFactory.decodeStream(data)
}
You need to open inputstream with
use
as it will automatically close the stream after operation complete.
Full method to get image uri from mobile gallery.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri filePath = data.getData();
try { //Getting the Bitmap from Gallery
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
rbitmap = getResizedBitmap(bitmap, 250);//Setting the Bitmap to ImageView
serImage = getStringImage(rbitmap);
imageViewUserImage.setImageBitmap(rbitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Use coil libray for this purpose on 2022.
https://coil-kt.github.io/coil/compose/
for jetpack compose
AsyncImage(
model = uriOfImage,
contentDescription = null,
)
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 want some help in creating thumbnail of a video being recorded from my android phone and I got this code from this Link, and I modified this part of the code to generate the thumbnail but somehow the thumbnail is not being generated, so any help will be appreciated.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == VIDEO_CAPTURED) {
videoFileUri = data.getData();
if (videoFileUri != null) {
Bitmap image= ThumbnailUtils.createVideoThumbnail(videoFileUri.toString(),MODE_APPEND);
ImageView imageView=(ImageView)findViewById(R.id.image);
imageView.setImageBitmap(image);
}
playVideoButton.setEnabled(true);
}
}
You can use glide. its automatically set thumb image of video.
Glide is also able to display the thumbnail of videos, as long as they're stored on the phone. Let's assume you get the file path by letting the user select a video: Based on this document https://futurestud.io/tutorials/glide-displaying-gifs-and-videos
String filePath = "/storage/emulated/0/Pictures/example_video.mp4";
Glide
.with(context)
.asBitmap()
.load(Uri.fromFile(new File(filePath)))
.into(imageViewGifAsBitmap);
Here is the complete tested working solution:
Try it.
if (videoFileUri != null) {
Bitmap bitmapThumb = null;
try {
bitmapThumb = ThumbnailUtils.createVideoThumbnail(videoFileUri.toString(),
MediaStore.Video.Thumbnails.MINI_KIND);// MINI_KIND, size: 512 x 384 thumbnail | MICRO_KIND, size: 96 x 96 thumbnail
ImageView imageView = (ImageView) findViewById(R.id.image);
// imageView.setImageBitmap(bitmapThumb);
Uri uri = getImageUri(context, bitmapThumb);
Picasso.with(context)
.load(uri)
.placeholder(R.drawable.ic_imagedefault)
.error(R.drawable.ic_imagedefault)
.resize(350, 200)//as per need.
.centerCrop()
.into(imageView);
} catch (Exception e) {
e.printStackTrace();
} finally {
bitmapThumb = null;
}
}
}
Here is the static method for getImageUri :
public static Uri getImageUri(Context inContext, Bitmap inImage) {
try {
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);
} catch (Exception e) {
e.printStackTrace();
return Uri.parse("");
}
}
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(filePath, MediaStore.Video.Thumbnails.MICRO_KIND);
This works fine for me.
https://developer.android.com/reference/android/media/ThumbnailUtils
Uri uri = getImageUri(context, bitmapThumb);
Glide.with(getContext()).
load(uri).
thumbnail(0.1f).
into(imageView);
I want to make service for imageuploading using retrofit2 or Okhttp3,
CODE :
public class GreenFragment extends Fragment {
#I omitted onCreateView that is for checking permission and trigger startGallry()
private void startGallery() {
Intent cameraIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
cameraIntent.setType("image/*");
if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(cameraIntent, 1000);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == Activity.RESULT_OK) {
if(requestCode == 1000){
Uri returnUri = data.getData();
Bitmap bitmapImage = null;
try {
bitmapImage = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), returnUri);
} catch (IOException e) {
e.printStackTrace();
}
mImageview.setImageBitmap(bitmapImage);
}
}
Uri returnUri;
returnUri = data.getData(); #This is what i want to control
}
#OnClick(R.id.btn_post)
public void onClick(View view) {
#Here is what i ask, How can i use retrunUri on here?
#On Android studio, retrunUri's font color is red, and not works.
Bitmap bitmap = getBitmapFromUri(returnUri);
File imageFile = createFileFromBitmap(bitmap);
RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("name", makeImageFileName() , RequestBody(MediaType.parse("image/png"), imageFile))
.build();
PostApiService.uploadFile(body);
}
# getBitmapFromUri(Uri uri) is for get Bitmap from uri, I omitted opts(options)
private Bitmap getBitmapFromUri(Uri uri) throws IOException {
ParcelFileDescriptor parcelFileDescriptor =
getActivity().getContentResolver().openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap resizedBitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, opts);
parcelFileDescriptor.close();
return resizedBitmap;
}
#createFileFromBitmap(Bitmap bitmap) is for making File from Bitmap
private File createFileFromBitmap(Bitmap bitmap) throws IOException {
File newFile = new File(getActivity().getFilesDir(), makeImageFileName());
FileOutputStream fileOutputStream = new FileOutputStream(newFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
fileOutputStream.close();
return newFile;
}
#ImageFileName() is for setting filename
private String makeImageFileName() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd_hhmmss");
Date date = new Date();
String strDate = simpleDateFormat.format(date);
return strDate + ".png";
}
What I want to know is how to use returnUri which is from onActivityResult, in public void onClick(View view)?
I want to use returnUri in public void onClick(View view).
I used an example which is from youtube, but it's too hard for me to understand perfectly,
So please help me.
modify the onActiivtyResult then handle the Exception in OnClick
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == Activity.RESULT_OK) {
if(requestCode == 1000){
Uri returnUri = data.getData();
Bitmap bitmapImage = null;
try {
bitmapImage = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), returnUri);
} catch (IOException e) {
e.printStackTrace();
}
mImageview.setImageBitmap(bitmapImage);
}
}
returnUri = data.getData(); //This is what i want to control
}
Uri returnUri;
In android, I open a bitmap from the image picker, and load it into a imageview. If the user selects a big image, the app will crash. I tried try/catch, but it didn't work.
Is there a way to check the file size before loading it into a bitmap?
This is the code:
This is the return function from when I choose an image
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
ImageUploadHandler.handleResult(this, data);
}
}
this is from another file
public void handleResult(Context context, Intent data) {
Bitmap bitmap = null;
try {
bitmap = MyImage.GetBitmapFromPath(context, data.getData());
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 100, out);
int size = out.size();
isReady = size <= IMAGE_THRESHOLD;
} catch (Exception e) {
isReady = false;
Log.d("Image Error", e.getMessage());
}
if (isReady) {
DialogImageView.setImageBitmap(bitmap);
DialogStatus.setText(context.getString(R.string.image_ok));
} else {
DialogImageView.setImageDrawable(null);
DialogStatus.setText(context.getString(R.string.too_big_image));
}
}
another file
public static Bitmap GetBitmapFromPath(Context context, Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String filePath = cursor.getString(column_index);
cursor.close();
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
return bitmap;
}
This line
bitmap = MyImage.GetBitmapFromPath(context, data.getData());
from the handleResult function, causes a outofmemory error when a user loads a big image.
How can I fix this?
Thanks.
try code similar to this, you just need to get a File object from the Bitmap you intend to check:
File file = new File(uri); // or new File(filePath);
file.length() // should give you a file size in bytes
I'm a noob to android and i want to set an ImageButton image with a file form the SDcard. However, getBitmap isn't creating a working bitmap. When i set the ImageButton with the bitmap that has just been created, the dimensions of the imageButton change but the image doesn't appear. This is really frustrating and Any help resolving this is greatly appreciated.
MYCODE
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE:
// If the file selection was successful
if (resultCode == RESULT_OK) {
if (data != null) {
// Get the URI of the selected file
final Uri uri = data.getData();
try {
// Create a file instance from the URI
final File file = FileUtils.getFile(uri);
Toast.makeText(Profile_Barber.this,"File Selected: "+file.getAbsolutePath(), Toast.LENGTH_LONG).show();
Log.e("URI", uri.toString());//Returns: content://media/external/images/media/1834
Bitmap bmp = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
if(bmp==null){
Log.e("BMP NULL", "This that bullshit!");
}else{
Log.e("BMP NOT NULL", bmp.toString()); //Returns: BMP NOT NULL android.graphics.Bitmap#4152b5a0
profilepic.setImageBitmap(bmp);
}
} catch (Exception e) {
Log.e("FileSelectorTestActivity", "File select error", e);
e.printStackTrace();
}
}
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
How about using this to decode image?
Uri contentURI = Uri.parse(data.getDataString());
ContentResolver cr = getContentResolver();
InputStream in = cr.openInputStream(contentURI);
Bitmap pic = BitmapFactory.decodeStream(in,null,null);