前言:
原以为只是个图片加载问题,结果绕了一圈,发现是 Glide、Bitmap、View 三者联动下的隐秘 Bug。这是一篇关于图片透明圆角被“吃掉”的终极分析与解决方案。
背景描述:透明圆角图片失效的奇怪现象
在 Android 项目中,我们有一张设计师提供的 PNG 图片,带有透明圆角(四角透明,非遮罩绘制)。在 ImageView 中直接设置资源或 Glide 加载该图片时,出现了神奇的现象:
直接设置: imageView.setImageResource(R.drawable.xxx) → 显示正常,圆角透明区域完整;
Glide 加载: Glide.with(...).load(...).into(imageView) → 某些设备或首次加载时,圆角消失,变成实心矩形。
更奇怪的是,加载一张其他尺寸图片后再加载原图,圆角又出现了……
原因分析:Glide 的默认 Bitmap 操作会“硬编码”处理 Alpha
核心问题:Glide 默认会对 Bitmap 进行一次“隐式转换”,影响透明区域,即使我没有手动调用 .transform(),Glide 仍然默认执行了一系列与尺寸、格式和缓存相关的 Transformation,其中包括:
- 硬编码 bitmap config 为 RGB_565 或 ARGB_8888
- Bitmap 可能未设置 hasAlpha = true
- 默认使用 BitmapPool,复用带错状态的 Bitmap
这种默认行为在某些场景中会抹掉 alpha 通道,导致圆角透明部分直接显示为实色。
关键源码分析:默认 Transformation 怎么影响透明通道?
我们从 Glide 的 BitmapDrawableTranscoder、Downsampler 和 DecodeJob 入手。
- Glide 加载流程核心链路(简化版)
ModelLoader → Decoder → Downsampler → BitmapPool → Transformation → Target
其中,默认路径会走:
Transformation<Bitmap> = CenterCrop 或 FitCenter
即使我没有调用 .transform(...),Glide 默认依然会套用一种尺寸适配策略,而这些 Transformation 最终会调用:
Bitmap result = bitmapPool.get(..., Bitmap.Config.ARGB_8888);
result.setHasAlpha(false); // 或未设置,默认是 false!
于是就有:
-
原图带透明;
-
结果 Bitmap 不支持透明;
-
合成图时透明区域被填色(通常是黑或白),圆角失效。
实验一下:默认行为是如何“吃掉”圆角的?
Glide.with(context)
.load(R.drawable.rounded_image) // 这是透明圆角 PNG
.into(imageView)
- 圆角 正常情况:直接使用 setImageResource,或自定义BitmapFactory 解码(保留透明)
- 圆角 被抹掉情况:使用 Glide 默认加载逻辑(无 .transform())
加入 .dontTransform() 后:
Glide.with(context)
.load(R.drawable.rounded_image)
.dontTransform()
.into(imageView)
圆角恢复解决方案:明确关闭默认 Transform
Glide.with(context)
.load(imageUrl)
.dontTransform() // 关闭默认 CenterCrop/FitCenter 等 transform
.format(DecodeFormat.PREFER_ARGB_8888) // 强制启用透明支持
.into(imageView)
当然也可以加上以下操作,组成防御性编程,防止使用 BitmapPool 中可能“污染过”的旧 Bitmap。
.skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE)
延伸分析:为啥小图 -> 大图能恢复圆角?问题找到了之后,就有个问题,为什么切换不同尺寸的图片之后,圆角就会出现呢?
背后原因是:
-
小图尺寸不匹配 Glide 的缓存条件,触发重新解码
-
可能跳过了默认的 Transform 流程(或 BitmapPool 无可复用项)
-
重新创建了支持透明的 Bitmap
这个现象正好印证了:BitmapPool 的状态(如 hasAlpha)影响下一次加载图像的结果。
这类“隐形 Bug”最可怕的是:它不是代码出错,而是框架默认逻辑与我们的的预期发生偏差。在实际开发中,多理解像 Glide 这样的图片库内部机制,能规避很多非显性问题。