本文为您介绍 Glide 接入 veImageX 提供的 HEIF 解码库的接入流程,实现 HEIF 加载。
当前仅支持解码 HEIF 静图,HEIF 动图暂不支持。
建议使用 4.0.0 及以上版本的 Glide。
您已完成独立 HEIF 编解码库的集成准备。
在 project 根目录下的build.gradle
下配置服务,代码示例如下所示:
maven { url 'https://artifact.bytedance.com/repository/Volcengine/' // 最新版本号获取地址:https://artifact.bytedance.com/repository/Volcengine/ }
说明
Glide 为开源图片库,建议您使用 4.0.0 及以上版本,具体版本号请见 Glide 版本历史。
在 module 目录下的build.gradle
文件中的dependencies
中添加 SDK 依赖,代码示例如下所示。
dependencies { implementation("com.github.bumptech.glide:glide:xxx") // Glide 库(推荐 4.0.0 及以上版本) annotationProcessor("com.github.bumptech.glide:compiler:xxx") //Glide 库解码能力(推荐 4.0.0 及以上版本) }
如果您使用 Kotlin 语言来编写 AppGlideModule
,您需要使用 kapt 或者 ksp 插件实现编译处理,推荐您使用 ksp 插件。
在dependencies
中添加 SDK 依赖。
dependencies { implementation("com.github.bumptech.glide:glide:xxx") // Glide 库(推荐 4.0.0 及以上版本) ksp("com.github.bumptech.glide:ksp:xxx") // 使用 KSP 插件替代传统 Kotlin 注解处理器(推荐 4.0.0 及以上版本) }
在自定义的Application
的onCreate
方法中执行以下代码:
List<String> encodedAuthCode = new ArrayList<>(); encodedAuthCode.add("xxxxxxxxxxxxxxxxxxxxxxxxx"); InitConfig initConfig = new InitConfig( this, // Application Context "000000", // App id, 如实填写,您可在 接入准备-获取 AppID 获取 "sample", // App Name,暂未用到,传入app名称 "debug", // channel,暂未用到,传入例如OPPO "0.0.1", // App的versionName, 如实填写 "1", // App的versionCode, 如实填写 "48144589260", // device id,暂未用到 InitConfig.CHINA, // App 上线的区域,如实填写 "M2ZmYzkzZjUtN2", // Token,如实填写,您可在 接入准备-获取 Token 获取 encodedAuthCode // 授权码List<String>,如实填写,您可在 接入准备-购买授权 获取 ); CloudControl.init(initConfig);
基于 HEIF 解码库配置 Glide 解码器插件,在 decode
方法中接入 veImageX HEIF 解码库,具体参考 Glide 官方文档中的自定义组件模块,代码示例如下所示。
说明
若 HEIF 图不包含 Alpha 通道,但仍选择使用Heif.toRgb565()
解码时,将可能导致最终图片解析异常。
class HeifByteBufferBitmapDecoder(bitmapPool: BitmapPool) : ResourceDecoder<ByteBuffer, Bitmap> { private val bitmapPool: BitmapPool init { this.bitmapPool = Preconditions.checkNotNull(bitmapPool) } override fun handles(source: ByteBuffer, options: Options): Boolean { val buffer = ByteBufferUtil.toBytes(source) return Heif.isHeif(buffer, buffer.size) } override fun decode( source: ByteBuffer, width: Int, height: Int, options: Options ): Resource<Bitmap>? { // 将 ByteBuffer 转为 buffer 数组 val buffer = ByteBufferUtil.toBytes(source) var hasAlpha = true // 解析图片的基本信息 val meta = Heif.parseSimpleMeta(buffer, buffer.size) meta ?: return null if (meta.size > 8) { // 是否有 alpha 通道 hasAlpha = meta[8] != 0 } // 根据是否有 alpha 通道,选择解码成不同格式 val heifData = if (hasAlpha) { // 包含,使用 heif toRgba 解码 Heif.toRgba(buffer, buffer.size, false, 1, 0, 0, meta[1], meta[0]) } else { // 不包含,使用 heif toRgb565 解码 // 注意:如果有 alpha 通道的图片强行使用 toRgb565 方式解码,可能会造成图片解析异常。 Heif.toRgb565(buffer, buffer.size, false, 1, 0, 0, meta[1], meta[0]) } heifData ?: return null val config: Bitmap.Config = if (hasAlpha) { Bitmap.Config.ARGB_8888 } else { Bitmap.Config.RGB_565 } val bitmap = heifData.newBitmap(config) // 将 HEIF 图片解码为 Bitmap return BitmapResource.obtain(bitmap, bitmapPool) } }
使用 prepend
方法注册 HeifByteBufferBitmapDecoder
解码器,并将其指定为解码 HEIF 图像时的最高优先级解码器。以便在使用 Glide 解码 HEIF 图像时,默认会优先使用该自定义解码器。
说明
对于加载某些在线 HEIF 图像出现的异常,建议参考使用 Glide 自定义解码器插件时处理 HEIF 图时加载异常的排查建议处理。
@GlideModule open class HeifGlideModule : AppGlideModule() { override fun registerComponents( context: Context, glide: Glide, registry: Registry ) { val byteBufferBitmapDecoder = HeifByteBufferBitmapDecoder(glide.bitmapPool) // 优先使用 prepend 注册的解码器 registry.prepend( Registry.BUCKET_BITMAP, ByteBuffer::class.java, Bitmap::class.java, byteBufferBitmapDecoder ) } }
如果您是在单独的模块中封装 Glide 框架,而不是在主应用程序模块中使用 Glide,请您将 AppGlideModule
更改为 LibraryGlideModule
。
参考 Glide 官方文档加载 HEIF 图片,具体如下所示。
Glide.with(context) .load("http://xxxxx.heic") // HEIF 图片的加载 URL .into(imageView)
检查依赖配置:确保HeifGlideModule
类在编译构建后成功生成有效的注册代码。如果HeifGlideModule
没有被其他类引用到,通常是因为 Gradle 文件配置的问题,请检查是否正确配置了 Glide 依赖,确保配置正确并成功生成目标文件。
检查注册方法:确保使用registry.prepend()
接口进行解码器注册。如果您使用的是 append
方法注册,那么当 Glide 自带的解码器能够处理 HEIF 图时,将会优先使用自带解码器拦截,最终导致自定义的解码器无法得到执行。
检查缓存策略:在 Glide 中,当您需要使用自定义解码器插件处理 HEIF 时,如果设置了跳过磁盘缓存策略,Glide无法优先使用自定义解码器对图片进行解码,而会默认使用自带的解码器,这可能导致 HEIF 图像解码异常。此时,建议您采取以下操作进行排查和处理:
检查缓存策略:请确保没有设置跳过磁盘缓存的相关策略,如.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
或.diskCacheStrategy(DiskCacheStrategy.NONE)
。这样 Glide 才能将图像保存到磁盘缓存,并使用自定义解码器进行解码。
清理缓存:如果之前已经设置了跳过磁盘缓存策略,或者存在旧的缓存数据,建议清理缓存。通过清理缓存,可以删除旧的缓存文件,以防止其对解码效果产生影响。您可以使用 Glide 提供的缓存清理方法或手动删除相关缓存文件。