📜  在 Android 中实现 ImageDecoder API

📅  最后修改于: 2022-05-13 01:58:44.916000             🧑  作者: Mango

在 Android 中实现 ImageDecoder API

我们在 Android 中使用了很多位图和可绘制对象。处理位图转换需要大量代码,而且我们经常遇到最喜欢的错误,即“内存不足”异常。 BitmapFactory 用于操作 Bitmaps,但在 Android P 中,我们有 ImageDecoder,它允许我们将 PNG、JPEG 等图像转换为 Drawables 或 Bitmaps。我们现在将详细介绍以下所有主题:

  1. 了解源和加载图像
  2. 从 Drawable 文件夹解码
  3. URI 覆盖源的默认设置
  4. 解码 GIF 和 WebP 错误处理

了解源和图像加载

在我们可以解码任何东西之前,我们必须首先映射图像源。源相当于 ImageDecoder 接受的路径。我们用来创建一个源

val gfg = ImageDecoder.createSource(file_path_of_your_image)

在这种情况下,可以在任何线程上生成源。但是,解码应该在后台线程中完成。

imageView.setImageDrawable(your_drawable_file)

我们使用 decodeDrawable 方法获取可绘制对象,但我们将使用 decodeBitmap函数从指定源获取位图。

val bmp:Bitmap = ImageDecoder.decodeBitmap(your_source_file)

前面的用例是从文件路径生成源并将其解码为 Drawable 或 Bitmap。同样,我们可以从 ByteBuffer 构造一个源,如下所示:

val file = ImageDecoder.createSource(byte_files)

可绘制文件夹和 URI 解码

考虑一个场景,我们项目的可绘制文件夹中有 PNG 或 JPEG。然后我们可以从资源文件夹中制作一个源,例如,

val file = ImageDecoder.createSource(resources, R.drawable.gfg_logo)

我们正在使用 ImageDecoder 从可绘制对象中获取 PNG 图标 ic 位置并为其创建源。现在我们可以使用 Drawable 或 Bitmap 来解码源。

val file: Drawable = ImageDecoder.decodeDrawable(source_file)

SetImageDrawable 和 setImageBitmap 可用于将这些转换为 ImageView。类似地,如果我们有一个 URI 并希望从中创建一个源,我们使用内容解析器来做到这一点。

val file_source = ImageDecoder.createSource(contentResolver, image_uri)

最后,如果我们需要从资产的文件中创建源,我们使用它。

val file_name = ImageDecoder.createSource(assetManager, some_asset)

覆盖源的默认设置

我们可以在创建源时覆盖从 Image 获得的默认设置。我们利用它来更改默认配置。我们使用 onHeaderDecodedListener 来添加监听器。

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)


Kotlin
val img_drawable = ImageDecoder.decodeDrawable(img_source)
if (img_source is AnimatedImageDrawable) {
    drawable.start()
}


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
        }
    }
}


Kotlin
val gfgListner: OnHeaderDecodedListener = object : OnHeaderDecodedListener {
    override fun onHeaderDecoded(decoder: ImageDecoder, info: ImageInfo, source: ImageDecoder.Source) {
        decoder.setPostProcessor { canvas ->
              
        }
    }
}


侦听器可用于各种转换

解码器允许我们进行转换,而信息包含原始图像的所有数据,例如 Mime 类型、大小、是否动画以及来源。如果我们想调整图像大小,请考虑我们将在 onHeaderDecoded函数中放入的内容。

decoder.setTargetSize(50,50)

WebP 和 GIF 解码

如果我们有 GIF 和 WebP 文件,我们可以单独使用 ImageDecoder 加载所有帧的动画和过渡,而不需要第三方库。假设我们有一个 Gif 文件作为 assets 文件夹的源。所以,为了在 Drawable 中解码并开始动画

val img_source = ImageDecoder.createSource(assetManager, your_asset_file)

科特林

val img_drawable = ImageDecoder.decodeDrawable(img_source)
if (img_source is AnimatedImageDrawable) {
    drawable.start()
}

错误处理

我们在解码源代码时可能会遇到问题。要检测问题,我们必须将 OnHeaderDecodedListener 中的解码器参数设置为 setOnPartialImageListener,如下所示。

科特林

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
        }
    }
}

我们在 setOnPartialImageListener 内部得到了异常,这就是我们可以记录错误的地方。当我们要记录错误时,exception.error 可能会返回以下错误之一:

  • 源异常 是源异常。
  • SOURCE INCOMPLETE — 源数据丢失。
  • 来源畸形数据 – 编码数据格式错误并包含错误。

很高兴知道

我们可以在图像加载完成后进行一些处理,例如添加自定义背景等。

OnHeaderDecodedListener

我们通过以下方式使用它进行处理:

科特林

val gfgListner: OnHeaderDecodedListener = object : OnHeaderDecodedListener {
    override fun onHeaderDecoded(decoder: ImageDecoder, info: ImageInfo, source: ImageDecoder.Source) {
        decoder.setPostProcessor { canvas ->
              
        }
    }
}

在这里,在 setOnProcessor 下,我们获得了画布,当图像被解码和加载时,我们将在其上执行更改并应用自定义效果。这就是 ImageDecoder 在您的应用程序中的使用方式。要在您的项目中运行,您需要 Android Pie 或更高版本。