在 Android 中实现 ImageDecoder API
我们在 Android 中使用了很多位图和可绘制对象。处理位图转换需要大量代码,而且我们经常遇到最喜欢的错误,即“内存不足”异常。 BitmapFactory 用于操作 Bitmaps,但在 Android P 中,我们有 ImageDecoder,它允许我们将 PNG、JPEG 等图像转换为 Drawables 或 Bitmaps。我们现在将详细介绍以下所有主题:
- 了解源和加载图像
- 从 Drawable 文件夹解码
- URI 覆盖源的默认设置
- 解码 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 — 源数据丢失。
- 来源畸形数据 – 编码数据格式错误并包含错误。
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.
很高兴知道
我们可以在图像加载完成后进行一些处理,例如添加自定义背景等。
OnHeaderDecodedListener
我们通过以下方式使用它进行处理:
科特林
val gfgListner: OnHeaderDecodedListener = object : OnHeaderDecodedListener {
override fun onHeaderDecoded(decoder: ImageDecoder, info: ImageInfo, source: ImageDecoder.Source) {
decoder.setPostProcessor { canvas ->
}
}
}
在这里,在 setOnProcessor 下,我们获得了画布,当图像被解码和加载时,我们将在其上执行更改并应用自定义效果。这就是 ImageDecoder 在您的应用程序中的使用方式。要在您的项目中运行,您需要 Android Pie 或更高版本。