Android 大图显示策略优化显示(二)

Glide有2种获取图片宽高的方式:

通过添加 RequestListener 并设置 override(Target.SIZE_ORIGINAL),可以在图片解码前获取其原始尺寸信息。

复制代码
Glide.with(context)
    .asBitmap()
    .load(R.drawable.your_image) // 或 Uri、URL、文件路径
    .override(Target.SIZE_ORIGINAL) // 请求原始尺寸
    .addListener(object : RequestListener<Bitmap> {
        override fun onResourceReady(
            resource: Bitmap?,
            model: Any?,
            target: Target<Bitmap>?,
            dataSource: DataSource?,
            isFirstResource: Boolean
        ): Boolean {
            resource?.let {
                val width = it.width
                val height = it.height
                // 在此处处理获取到的宽高
                Log.d("GlideSize", "Width: $width, Height: $height")
            }
            return true // 返回 true 阻止图片传递给 ImageView
        }

        override fun onLoadFailed(
            e: GlideException?,
            model: Any?,
            target: Target<Bitmap>?,
            isFirstResource: Boolean
        ): Boolean {
            return false
        }
    })
    .preload() // 仅预加载,不显示

第二种方式:

通过 SimpleTarget 的回调获取尺寸后立即释放资源,避免内存占用

复制代码
Glide.with(context.applicationContext) // 使用 ApplicationContext 避免生命周期问题
    .asBitmap()
    .load(R.drawable.your_image)
    .into(object : SimpleTarget<Bitmap>() {
        override fun onResourceReady(
            resource: Bitmap,
            transition: Transition<in Bitmap>?
        ) {
            val width = resource.width
            val height = resource.height
            // 处理获取到的宽高
            resource.recycle() // 获取尺寸后立即回收 Bitmap
        }
    })
  1. 性能优化 ‌:方法一通过 override(Target.SIZE_ORIGINAL)preload() 组合,能最大程度减少内存使用,仅解码图片头部信息获取尺寸1。
  2. 生命周期管理 ‌:如果仅需获取尺寸而不涉及 UI 更新,建议使用 ApplicationContext 以避免内存泄漏2。
  3. 网络图片‌:对于网络图片,Glide 会先下载图片头部信息来获取尺寸,不会下载完整图片数据1。
  4. 回调处理‌:两种方法均为异步操作,获取到的宽高需在回调中处理。

根据上篇文章的思想继续优化:

复制代码
private fun loadImageToView(
        context: Context,
        maxWidth: Int,
        maxHeight: Int,
        resId: Int,
        igvTarget: ImageView
    ) {
        Glide.with(context)
            .asBitmap()
            .load(resId) // 或 Uri、URL、文件路径
            .override(Target.SIZE_ORIGINAL) // 请求原始尺寸
            .addListener(object : RequestListener<Bitmap> {
                override fun onResourceReady(
                    resource: Bitmap,
                    model: Any,
                    target: com.bumptech.glide.request.target.Target<Bitmap>,
                    dataSource: DataSource,
                    isFirstResource: Boolean
                ): Boolean {
                    resource?.let {
                        val width = it.width
                        val height = it.height
                        // 在此处处理获取到的宽高
                        Log.d("GlideSize", "Width: $width, Height: $height")
                        val scaleResult =
                            ImageUtils.calculateScaleParameters(
                                maxWidth,
                                maxHeight,
                                width,
                                height
                            )
                        runOnUiThread {
                            igvTarget.layoutParams.height = scaleResult.newHeight
                            igvTarget.layoutParams.width = scaleResult.newWidth
                            Glide.with(context).load(resId).into(igvTarget)
                        }
                    }
                    return true // 返回 true 阻止图片传递给 ImageView
                }

                override fun onLoadFailed(
                    e: GlideException?,
                    model: Any,
                    target: com.bumptech.glide.request.target.Target<Bitmap>,
                    isFirstResource: Boolean
                ): Boolean {
                    return false
                }
            })
            .preload() // 仅预加载,不显示
    }

    private fun loadImageToView(
        context: Context,
        maxWidth: Int,
        maxHeight: Int,
        path: String,
        igvTarget: ImageView
    ) {
        Glide.with(context)
            .asBitmap()
            .load(path) // 或 Uri、URL、文件路径
            .override(Target.SIZE_ORIGINAL) // 请求原始尺寸
            .addListener(object : RequestListener<Bitmap> {
                override fun onResourceReady(
                    resource: Bitmap,
                    model: Any,
                    target: com.bumptech.glide.request.target.Target<Bitmap>,
                    dataSource: DataSource,
                    isFirstResource: Boolean
                ): Boolean {
                    resource?.let {
                        val width = it.width
                        val height = it.height
                        // 在此处处理获取到的宽高
                        Log.d("GlideSize", "Width: $width, Height: $height")
                        val scaleResult =
                            ImageUtils.calculateScaleParameters(
                                maxWidth,
                                maxHeight,
                                width,
                                height
                            )
                        runOnUiThread {
                            igvTarget.layoutParams.height = scaleResult.newHeight
                            igvTarget.layoutParams.width = scaleResult.newWidth
                            Glide.with(context).load(path).into(igvTarget)
                        }
                    }
                    return true // 返回 true 阻止图片传递给 ImageView
                }

                override fun onLoadFailed(
                    e: GlideException?,
                    model: Any,
                    target: com.bumptech.glide.request.target.Target<Bitmap>,
                    isFirstResource: Boolean
                ): Boolean {
                    return false
                }
            })
            .preload() // 仅预加载,不显示
    }
相关推荐
HDO清风4 小时前
CASIA-HWDB2.x 数据集DGRL文件解析(python)
开发语言·人工智能·pytorch·python·目标检测·计算机视觉·restful
2201_756989094 小时前
C++中的事件驱动编程
开发语言·c++·算法
会飞的战斗鸡4 小时前
JS中的链表(含leetcode例题)
javascript·leetcode·链表
多米Domi0115 小时前
0x3f 第48天 面向实习的八股背诵第五天 + 堆一题 背了JUC的题,java.util.Concurrency
开发语言·数据结构·python·算法·leetcode·面试
2301_822377655 小时前
模板元编程调试方法
开发语言·c++·算法
csbysj20205 小时前
Python 循环嵌套
开发语言
测试_AI_一辰5 小时前
Agent & RAG 测试工程05:把 RAG 的检索过程跑清楚:chunk 是什么、怎么来的、怎么被命中的
开发语言·人工智能·功能测试·自动化·ai编程
Coding茶水间5 小时前
基于深度学习的输电电力设备检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
开发语言·人工智能·深度学习·yolo·目标检测·机器学习
清风~徐~来5 小时前
【视频点播系统】BRpc 介绍及使用
开发语言
啟明起鸣5 小时前
【C++ 性能提升技巧】C++ 的引用、值类型、构造函数、移动语义与 noexcept 特性,可扩容的容器
开发语言·c++