相关文章推荐
道上混的鸭蛋  ·  spring data ...·  9 月前    · 
愉快的猴子  ·  C# JSON ...·  1 年前    · 
针对4.+

implementation 'jp.wasabeef:glide-transformations:4.1.0'

Glide.with(context).load(url).apply(RequestOptions.bitmapTransform(new BlurTransformation(25,8))).into(view);

这里 BlurTransformation 第一个参数是1-25范围,随着数字越大,模糊度越高,第二个参数代表采样率,数字越大,越模糊

通过源码可以看到, sampling 数值越大,scaledWidth, scaledHeight区域越小,采样的内容越少,模糊后的背景可能只有原图的部分轮廓(可以理解放大部分区域)

代码中原始的sampling 是 1;当然,如果你sampling 设置的大一些是可以减少性能损耗的;

通过源码分析,可知,Glide 也是使用FastBlur 进行的模糊处理

fastBlur算法它直接在Java层做图片的模糊处理。对每个像素点应用高斯模糊计算、最后在合成Bitmap。就一个方法,使用这种方式不会有兼容性问题,也不会引入jar包导致APK变大。但是这种方法的效率是非常低的,想想也知道,因为是在Java 层处理,速度会更慢。将Bitmap全部加载到内存,较大图片容易OOM。

fastBlur 进行模糊处理的源码就不贴了;

Glide 模糊图片,对于大图尽量进行压缩后再模糊,或者调大sampling数值(以2的整数倍)

2、RenderScript

RenderScript是在Android上的高性能运行密集型运算的框架。
是在Android3.0(API 11)引入的。而Android图片高斯模糊处理,通常也是用这个库来完成。它提供了我们Java层调用的API,实际上是在c/c++ 层来处理的,所以它的效率和性能通常是最高的。
缺点是:但是它只能在API 17或者更高的版本使用。当然也可以引用兼容包,但是会增加一点包的体积。并且模糊度有有限。

上图是模糊原理;

我在这使用了一个三方库 github.com/mmin18/Real…

这个其实最终也是使用了RenderScript 来进行处理的

两者对比来看:推荐使用后者;

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

最近需求中,需要给DialogFragment 增加高斯模糊的背景;

其实有两种思路:

方案1、当弹出DialogFragment 的时候,对当前phoneWindow 窗口进行截图,然后对截取的图片进行高斯模糊;

方案2、在DialogFragment 的布局中增加一层Blur布局,当DialogFragment 显示的时候,对该层布局做高斯模糊;

两种方案实现效果大致相同,区别点:

方案一:由于采用的是截图,当弹窗出现的时候,截图撑满屏幕,那么用户看不到弹窗下真实的界面变化,如果截图过程中,界面还是白板或者一些初始化未加载的界面,

那么模糊蒙层就很丑陋;

方案二:弹窗显示的时候,用户不仅可以看到模糊蒙层,还可以透过蒙层看到下面真实界面动态变化,类似玻璃遮罩了一层;

这里推荐方案二:

1、implementation 'com.github.mmin18:realtimeblurview:1.2.1'

在DialogFragment 布局中增加一层,充当模糊蒙层玻璃遮罩

3、当然实现以上两步基本就可以实现效果了,

但是我在实现过程中依然发现两个问题:

1、在DialogFragment中,模糊蒙层blur_view 并未撑满全屏

2、顶部状态栏没有实现

问题一解决:

因为,由源码可以看到:

当mDialog.setContentView 执行之后,再调整dialog 的宽高和Grivaty

问题二解决:

1、dialogFragment 显示的Activity

设置them

android:theme="@style/Theme.AppCompat.NoActionBar"

2、DialogFragment onCreateView 方法中调用如下,实现顶部状态栏透明

ImmersionBar.with(this).transparentStatusBar().statusBarDarkFont(true, 0.2f).init()

3、在弹窗显示出来,模糊效果完成之后,再设置下statusBarColor,保证状态栏和模糊背景颜色一致

---------------------------------------------------------------------------------------------------------------------------------------------------

当然需求如果特殊,关于使用静态截图来做模糊背景的方案,这里再稍微写一下,模糊蒙层使用截图或者直接对图片进行模糊处理的方式:

1、Glide 方式

2、我使用的github.com/wasabeef/Bl… 这个库,源码 引入的方式

同样是处理 DiaglogFragment 背景模糊

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

先给结论:推荐使用底层以RenderScript为运算框架来实现的高斯模糊的方案;

比较优劣:

一、Glide:

1、由于Gilde 底层是以FastBlur来运算的,首先局限于算法的实现,会造成性能上的低效;

2、如果图片过大,还需要对图片进行压缩,或者如下图实时测量宽高来设置图片,其实也并不简单,类似如下图

3、Glide 在进行模糊的时候,BlurTransformation 传入的参数是有限制的,第一个参数是1-25,参数越大,模糊越高,第二个参数采样率,参数越大,采样区域越小

调整程度有限,实际效果可能达不到预期。

二、Blurry库和RealtimeBlurView

两者底层都是使用RenderScript来实现;

如果非要区别的话:

RealtimeBlurView 使用简单,只需要在XML中增加一个布局即可;

Blurry 封装性较好,灵活度高,适合复杂的高斯模糊场景;

所以根据你的需求,来合理选择即可~

  • 私信