Implement ImageDecoder API in Android - GeeksforGeeks

20 Dec, 2021
We use a lot of Bitmaps and drawables in Android. Handling bitmap conversions necessitates a significant amount of code, and we frequently encounter the favorite error, the “Out of Memory” exception. The BitmapFactory is used to manipulate Bitmaps, but with Android P, we have ImageDecoder, which allows us to convert images like PNG, JPEG, and so on to Drawables or Bitmaps. We will now go through all the below-mentioned topics in detail: 
Understanding the source and loading ImagesDecoding from the Drawable folderURI Overriding the source’s default settingsDecoding GIFs and WebP Error Handling
Understanding the source and loading Images
Decoding from the Drawable folder
URI Overriding the source’s default settings
Decoding GIFs and WebP Error Handling
Before we can decode anything, we must first map the image source. The source is equivalent to the ImageDecoder’s accepted path. We use to create a source
val gfg = ImageDecoder.createSource(file_path_of_your_image)
In this case, generating a source can happen on any thread. However, decoding should be done in the background thread.
imageView.setImageDrawable(your_drawable_file)
We’re using the decodeDrawable method to acquire a drawable, but we’ll use the decodeBitmap function to get a bitmap from the specified source.
val bmp:Bitmap = ImageDecoder.decodeBitmap(your_source_file)
The preceding use-case was to generate a source from a file path and decode it to Drawable or Bitmap. Similarly, we can construct a source from ByteBuffer as follows:
val file = ImageDecoder.createSource(byte_files)
Consider a scenario in which we have PNGs or JPEGs in our project’s drawable folder. Then we can make a source from the resource folder, for example,
val file = ImageDecoder.createSource(resources, R.drawable.gfg_logo)
We’re using ImageDecoder to get the PNG icon ic location from the drawable and create a source for it. Now we may use Drawable or Bitmap to decode the source.
val file: Drawable = ImageDecoder.decodeDrawable(source_file)
SetImageDrawable and setImageBitmap can be used to convert these to ImageView. Similarly, if we have a URI and wish to make a source out of it, we use a content resolver to do so.
val file_source = ImageDecoder.createSource(contentResolver, image_uri)
Finally, if we need to make a source from a file from an asset, we use it.
val file_name = ImageDecoder.createSource(assetManager, some_asset)
We can override the default settings we get from the Image while creating a source. We utilize this to alter the default configuration. We use the onHeaderDecodedListener to add the listener.
Kotlin
val gfgListner: OnHeaderDecodedListener = object : OnHeaderDecodedListener {    override fun onHeaderDecoded(decoder: ImageDecoder, info: ImageInfo, source: ImageDecoder.Source) {     // Your logic here.    }}val img_drawable = ImageDecoder.decodeDrawable(your_source, listener)
The decoder allows us to do transformations, while the information holds all of the original image’s data, such as Mime type, size, and whether or not it is animating, as well as the source. Consider what we would put inside the onHeaderDecoded function if we wanted to resize the image.
decoder.setTargetSize(50,50)
If we have GIFs and WebP files, we can load them with all of the frames’ animations and transitions using ImageDecoder alone, without the need for a third-party library. Let’s say we have a Gif file as a source from the assets folder. So, in order to decode it in Drawable and begin the animation
val img_source = ImageDecoder.createSource(assetManager, your_asset_file)
Kotlin
val img_drawable = ImageDecoder.decodeDrawable(img_source)if (img_source is AnimatedImageDrawable) {    drawable.start()}
We may encounter issues while decoding the source. To detect issues, we must set the decoder argument in OnHeaderDecodedListener to setOnPartialImageListener, as seen below.
Kotlin
val gfgListner: OnHeaderDecodedListener = object : OnHeaderDecodedListener {    override fun onHeaderDecoded(decoder: ImageDecoder, info: ImageInfo, your_source: ImageDecoder.Source) {        decoder.setOnPartialImageListener {exception->            Log.d("GfG Decoder",exception.error.toString()))            true        }    }}
We get the exception here, inside setOnPartialImageListener, and that’s where we can log the error. When we want to log an error, exception.error may return one of the following errors:
SOURCE EXCEPTION is a source exception.
SOURCE INCOMPLETE — the source data was missing.
SOURCE MALFORMED DATA – the encoded data was malformed and contained an error.
We’re returning true in this case, which means the listeners should only see the created image until the exception occurs. If it returns false, however, it will abort the execution and throw an exception.
We can apply some processing once the image has been loaded, such as adding a custom background, etc.
OnHeaderDecodedListener
We use it for processing in the following ways:
Kotlin
val gfgListner: OnHeaderDecodedListener = object : OnHeaderDecodedListener {    override fun onHeaderDecoded(decoder: ImageDecoder, info: ImageInfo, source: ImageDecoder.Source) {        decoder.setPostProcessor { canvas ->                      }    }}
Here, under setOnProcessor, we obtain the canvas on which we will perform our changes and apply custom effects when the Image has been decoded and loaded. This is how ImageDecoder can be used in your application. To run in your project, you’ll need Android Pie or higher.
Picked
Android
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Flutter - Custom Bottom Navigation Bar
Retrofit with Kotlin Coroutine in Android
Android Listview in Java with Example
GridView in Android with Example
How to Post Data to API using Retrofit in Android?
How to Read Data from SQLite Database in Android?
How to Change the Background Color After Clicking the Button in Android?
Fragment Lifecycle in Android
Animation in Android with Example
How to Add Image to Drawable Folder in Android Studio?