自定义Glide BlurTransformation半径超过25时失效问题求助
解决Glide自定义BlurTransformation半径超过25失效的问题
我完全懂你的困扰——自己手写的Glide模糊变换,一把radius设成25以上就直接失效,还不想引入第三方库对吧?这事儿根源很明确:RenderScript自带的ScriptIntrinsicBlur本身就把最大模糊半径限制在了25,超过这个值的参数会被直接忽略,所以咱们得手动绕开这个限制。
核心思路:多次迭代小半径模糊叠加
既然单次模糊最多只能到25,那我们就通过多次模糊来模拟大半径的效果。比如要实现50的模糊半径,就连续做两次25半径的模糊;如果要60,就做两次25加一次10,以此类推。虽然叠加出来的效果和原生大半径会有细微差异,但视觉上已经足够接近,完全能满足需求。
修改后的完整代码
我给你调整了原有的BlurTransformation,加入了大半径处理逻辑,还优化了资源回收和缓存策略:
public class BlurTransformation extends BitmapTransformation { private RenderScript rs; private float radius; // 允许传入自定义模糊半径,方便灵活调整 public BlurTransformation(Context context, float radius) { super(); rs = RenderScript.create(context); // 过滤掉无效的负数半径 this.radius = Math.max(0, radius); } @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) @Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { Bitmap blurredBitmap = toTransform.copy(Bitmap.Config.ARGB_8888, true); ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); // 处理超过25的大半径:循环迭代模糊 float remainingRadius = radius; while (remainingRadius > 25) { applyBlur(script, blurredBitmap, 25); remainingRadius -= 25; } // 处理剩余不足25的半径部分 if (remainingRadius > 0) { applyBlur(script, blurredBitmap, remainingRadius); } return blurredBitmap; } // 提取重复的模糊逻辑到单独方法,减少代码冗余 @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) private void applyBlur(ScriptIntrinsicBlur script, Bitmap bitmap, float currentRadius) { Allocation input = Allocation.createFromBitmap(rs, bitmap, Allocation.MipmapControl.MIPMAP_FULL, Allocation.USAGE_SHARED); Allocation output = Allocation.createTyped(rs, input.getType()); script.setInput(input); script.setRadius(currentRadius); script.forEach(output); output.copyTo(bitmap); // 及时释放Allocation资源,避免内存泄漏 input.destroy(); output.destroy(); } @Override public void updateDiskCacheKey(MessageDigest messageDigest) { // 把半径加入缓存Key,确保不同半径的模糊结果不会共用缓存 messageDigest.update(("blur transformation radius:" + radius).getBytes()); } // 销毁RenderScript资源,防止内存泄漏 @Override protected void finalize() throws Throwable { super.finalize(); rs.destroy(); } }
关键修改点说明
- 可配置半径:新增了带radius参数的构造方法,不用硬写25,灵活度更高
- 大半径处理:通过循环叠加多次25半径的模糊,实现超过25的模糊效果
- 资源优化:每次模糊后主动销毁
Allocation,并在类销毁时释放RenderScript,避免内存泄漏 - 缓存优化:把radius加入磁盘缓存Key,避免不同半径的模糊结果互相覆盖
使用示例
比如你需要设置50的模糊半径,直接这么用就行:
Glide.with(context) .load(yourImageUrl) .transform(new BlurTransformation(context, 50)) .into(yourImageView);
要是你追求更细腻的效果,也可以把每次迭代的半径调小(比如15),但次数越多性能消耗会越高,记得在效果和性能之间做权衡~
内容的提问来源于stack exchange,提问作者mW3
相关产品推荐
相关产品推荐

