How to get Bitmap from an Uri?
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
Loading an image from a Uri into a Bitmap is one of the most common tasks in Android development. Whether the user picks a photo from the gallery, your app receives a content URI from another app, or you download an image and store it locally, you will eventually need to decode that URI into pixel data you can display or manipulate. Android offers several APIs for this, and the right choice depends on your minimum API level and whether you need fine-grained control over decoding.
BitmapFactory with ContentResolver
The classic approach uses BitmapFactory.decodeStream() together with ContentResolver.openInputStream(). This works on all API levels and gives you direct access to the raw bitmap.
For large images, decoding the full resolution into memory can cause an OutOfMemoryError. You can sample down the image by reading its dimensions first and then setting inSampleSize:
ImageDecoder (API 28+)
Starting with Android 9 (API 28), ImageDecoder provides a modern, more capable API. It supports animated images (GIF, WebP), color space management, and post-processing in a single pipeline.
ImageDecoder also handles HEIF images natively, which BitmapFactory does not support on all devices. If your minimum SDK is 28 or higher, prefer this API.
Loading with Glide or Coil
In practice, most Android apps use an image loading library rather than decoding bitmaps manually. Glide and Coil handle caching, downsampling, lifecycle awareness, and background threading automatically.
Glide example:
Coil example (Kotlin-first):
Libraries like these are the right choice for display in UI. They decode on a background thread, respect the view's dimensions for automatic downsampling, and manage a disk and memory cache so you do not decode the same image twice.
Handling Rotation with ExifInterface
Photos taken with a camera often have an EXIF orientation tag that tells you the image is rotated 90, 180, or 270 degrees. BitmapFactory ignores this tag, so the decoded bitmap may appear sideways. You need to read the orientation and apply a matrix rotation manually.
Note that ImageDecoder and libraries like Glide handle EXIF orientation automatically, so you only need this fix when using BitmapFactory directly.
Common Pitfalls
- Decoding on the main thread:
BitmapFactory.decodeStream()performs disk I/O and can block the UI. Always decode on a background thread using coroutines,AsyncTask, or a library. - Not closing the InputStream: Failing to close the stream returned by
openInputStream()leaks file descriptors. Use Kotlin's.use {}extension or a try-finally block. - Ignoring inSampleSize for large images: A 12-megapixel photo decoded at full resolution consumes roughly 48 MB of heap. Without downsampling, loading a few images will crash the app with
OutOfMemoryError. - Forgetting EXIF rotation with BitmapFactory: The bitmap decodes successfully but displays rotated. Users see sideways photos and assume the app is broken. Always check EXIF orientation when using
BitmapFactory. - Using
MediaStore.Images.Media.getBitmap()(deprecated): This convenience method was deprecated in API 29 because it decodes at full resolution with no sampling control. Replace it withImageDecoderor manualBitmapFactorydecoding.
Summary
BitmapFactory.decodeStream()withContentResolveris the universal approach that works on all API levels. UseinSampleSizeto avoid out-of-memory errors.ImageDecoder(API 28+) is the modern replacement with built-in support for animated formats, HEIF, and automatic EXIF handling.- Glide and Coil handle caching, threading, and downsampling automatically and are the best choice for displaying images in UI.
- ExifInterface is required when using
BitmapFactoryto correct photo rotation;ImageDecoderand image libraries handle this for you. - Always decode images on a background thread and close input streams to avoid UI freezes and resource leaks.
Related reading
- How to go about searching for a player models in COD with OpenCV
- How to handle RGB images in Keras
- how to handle text and image input together in neural network algorithm
- How to implement an image2D array sequence sliding window in tensorflow?
- How to get Context in Android MVVM ViewModel
- How to get Context in Jetpack Compose
- How to implement Grad-CAM on a trained network
- How to implement multi-class semantic segmentation?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.