268

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?

Jonik
  • 80,077
  • 70
  • 264
  • 372
ilredelweb
  • 3,091
  • 4
  • 17
  • 14

24 Answers24

643

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

Mark Ingram
  • 71,849
  • 51
  • 176
  • 230
  • 3
    This code doesn't deal with bigger images though (basically anything wallpaper size). getBitmap() calls decodeStream() which fails with the OOM error from http://stackoverflow.com/questions/2220949/handling-large-bitmaps. Any other advice? MediaStore.Images.Thumbnails.getThumbnail() apparently does not take a contentURI. – pjv Jun 03 '11 at 11:16
  • 1
    See the answer here: http://stackoverflow.com/questions/4753013/how-to-load-tiles-from-a-large-bitmap-in-android – Mark Ingram Jun 03 '11 at 20:32
  • @MarkIngram Does this work with any local image or just the camera image? – Narendra Singh Jul 03 '15 at 06:12
  • @MarkIngram what if we dont have access to data.getData(), I mean if I simply open some image from gallery and I all know is about its path, how can I get uri and bitmap? – Umair Jun 25 '16 at 21:47
  • @Umair you should ask a new question instead of asking in the comments of an answer. By the way: have a look here https://developer.android.com/reference/android/net/Uri.html – winklerrr Jan 24 '17 at 11:31
  • It's telling me `Unhandled exception: java.io.IOException` with the red squiggly lines underneath. Any idea why? – Cullub Apr 14 '18 at 00:42
  • Well I ended up putting a try-catch statement around it, and it got rid of the error. I wonder why it requires you to catch possible errors... – Cullub Apr 14 '18 at 14:32
  • It throws IOException please update this answer with try catch block – Mohsin kazi Jul 29 '19 at 10:07
  • @Mohsinkazi, `try/catch` isn't relevant to the answer, and it certainly doesn't improve the readability of the code. – Mark Ingram Jul 29 '19 at 10:42
  • @MarkIngram I agree that try catch block doesn't necessary but in some situation getBitmap() method throws exception. It happened with me so I suggested to add try catch block to make this code more usable. – Mohsin kazi Jul 29 '19 at 10:49
  • @Mohsinkazi, the code isn't intended to be copy + pasted into a project without thought. It's merely providing an answer to the question. – Mark Ingram Jul 29 '19 at 11:39
  • @MarkIngram but not applicable for all those, who want Bitmap from an Uri. By the way thank you for your answer it help me. – Mohsin kazi Jul 29 '19 at 13:32
  • bitmap object is becoming empty. what i am doing wrong? – shyam.y Oct 14 '19 at 09:16
  • As [this link](https://developer.android.com/training/camera/photobasics.html#java) states, you get an image thumbnail, which is about 400x100 on modern devices. – Borzh Nov 23 '19 at 23:26
  • 19
    MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri); is depricated now – Rohit Singh Aug 15 '20 at 02:37
124

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:

Community
  • 1
  • 1
pjv
  • 10,658
  • 6
  • 43
  • 60
  • 1
    This really helped me, although I think it's worth mentioning that the this keyword can't be used from within a static context. I passed it into the getThumbnail method as an argument and it works like a charm. – MacKinley Smith Sep 16 '13 at 14:39
  • 9
    Can any one tell me what value should i give to THUMBNAILSIZE – Abid Dec 24 '14 at 07:46
  • 2
    Closing and reopening the InputStream is actually necessary because the first BitmapFactory.decodeStream(...) call sets the reading position of the stream to the end, so the second call of the method wouldn't work anymore without reopening the stream! – DominicM Jan 31 '15 at 21:11
  • THUMBNAILSIZE ,as the name suggests is the size of the image to be shown as a thumbnail ie. the thumbnail display size – Abx Jun 16 '15 at 10:45
  • it gives me java.io.FileNotFoundException: No content provider: – Fay007 Dec 22 '15 at 12:24
  • @war_Hero `THUMBNAILSIZE` should be the size of the view which is going to show the thumbnail. – winklerrr Jan 25 '17 at 12:15
  • 3
    It's unnecessary to calculate the ratio as a power of two by yourself because the decoder itself rounds to sample size down to the nearest power of two. Therefore the method call `getPowerOfTwoForSampleRatio()` can be skipped. See: https://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize – winklerrr Jan 25 '17 at 12:20
60

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

Alessandro Scarozza
  • 4,273
  • 6
  • 31
  • 39
Ika
  • 1,608
  • 14
  • 15
51
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

DjP
  • 4,537
  • 2
  • 25
  • 34
  • 2
    @Dhananjay Thank you, your hint saves my day, and it works to load the thumbnail bitmap from Content Provider. – Nezneika Oct 29 '13 at 09:52
  • 2
    In addition, the _Uri.parse()_ must contain URI format, just like: _Uri.parse("file:///mnt/sdcard/filename.jpg")_, if not we will get *java.io.FileNotFoundException: No content provider*. – Nezneika Oct 29 '13 at 10:13
  • Some editorialization would be nice, but this is a good concise answer to the OPs question that works in most cases. This is a nice answer to have on the page for the sake of distilling out the piece of these other answers that directly answer the OPs questions. – umassthrower Feb 04 '14 at 23:17
  • 2
    @AndroidNewBee c is Context object. – DjP Sep 27 '16 at 08:00
  • not working in my case getting exception Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference – K Guru Jan 09 '17 at 14:57
26
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();
    }
}
Rahul Gaur
  • 1,661
  • 1
  • 13
  • 29
DeltaCap019
  • 6,532
  • 3
  • 48
  • 70
  • 4
    it's works on all sdk.. Thanks. it's alternative way of `Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);` – Jigar Patel Jan 18 '17 at 10:12
  • 1
    MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri) is deprecated – oiyio May 04 '21 at 13:14
25

This is the easiest solution:

Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
Sheikh Hasib
  • 7,423
  • 2
  • 25
  • 37
12

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();
}
Emre AYDIN
  • 724
  • 8
  • 10
12
Uri imgUri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imgUri);
4b0
  • 21,981
  • 30
  • 95
  • 142
Ahmed Sayed
  • 155
  • 1
  • 2
6
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();
}
Mark S. Khalil
  • 113
  • 1
  • 4
5
private fun setImage(view: ImageView, uri: Uri) {
        val stream = contentResolver.openInputStream(uri)
        val bitmap = BitmapFactory.decodeStream(stream)
        view.setImageBitmap(bitmap)
}
J.Grbo
  • 435
  • 5
  • 11
4

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'
Abdur Rehman
  • 1,247
  • 10
  • 13
3

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)
    }
yaugenka
  • 2,602
  • 2
  • 22
  • 41
3
  InputStream imageStream = null;
    try {
        imageStream = getContext().getContentResolver().openInputStream(uri);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
3
ContentResolver cr = context.getContentResolver();
try (InputStream input = cr.openInputStream(url)) {
    Bitmap bitmap = BitmapFactory.decodeStream(input);
}
Ridcully
  • 23,362
  • 7
  • 71
  • 86
pseudoankit
  • 309
  • 2
  • 6
2

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;
    }
}
Fakhriddin Abdullaev
  • 4,169
  • 2
  • 35
  • 37
2

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 )
}
Cyrus
  • 8,995
  • 9
  • 31
  • 58
2

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)

Shwarz Andrei
  • 647
  • 14
  • 17
2
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.

1

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.

1

(KOTLIN) So, as of April 7th, 2020 none of the above mentioned options worked, but here's what worked for me:

  1. 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) }

  2. If you just want to set the bitmap to and imageView, use this:

    BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }

Advait
  • 574
  • 3
  • 12
1
* 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;
        }
Praful Parmar
  • 213
  • 2
  • 6
0

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();
      }


   }
}
Sabeeh
  • 1,123
  • 9
  • 11
0

A recurring problem that I faced using the solutions provided here is:

Failed to find provider info for com.samsung.systemui.navillera.navilleraprovider

This will prevent your bitmap from being loaded.

I tried this instead and it works! Praise God.

The explanation is that the uri provided needs to be converted into a file path.

Bitmap b1 = MediaStore.Images.Media.getBitmap(this.getContentResolver(), Uri.fromFile(new File(uri1.toString())));
Kevin
  • 109
  • 6
-1

Use coil libray for this purpose on 2022.

https://coil-kt.github.io/coil/compose/

for jetpack compose

            AsyncImage(
                model = uriOfImage,
                contentDescription = null,
            )