1. android13 FLAG_BLUR_BEHIND 壁纸高斯模糊,毛玻璃背景方案设计-千里马framework实战
高斯模糊在Android13中的实现,特别是FLAG_BLUR_BEHIND这一特性,为开发者提供了在不同场景下实现美观与交互提升的途径。此特性主要应用于状态栏下拉时展示桌面画面作为背景,并通过高斯模糊效果使其更加吸引人,与主要焦点形成对比。
实现方案通常分为两种。第一种为传统的截图方法,通过截取背景图像,应用高斯模糊处理,再将处理后的图像作为背景展示。此方法操作简单,灵活性大,但无法实现实时模糊,且修改逻辑较多。
第二种方案则是Android新版本提供的直接设置窗口属性的方法,通过设置FLAG_BLUR_BEHIND,让其后的窗口层实现实时的高斯模糊效果。此方法由系统底层提供,操作简便,无需额外处理,能实现实时模糊。然而,此方法仅适用于对窗口下方的元素进行模糊处理,可能导致窗口切换时出现bug。
具体使用FLAG_BLUR_BEHIND,可以通过设置Window的LayoutParams来实现。同时,还提供了setBlurBehindRadius方法来调整模糊程度,其中mBlurBehindRadius越大,模糊效果越明显。通过对比模糊前后的图像效果,可以直观地感受到高斯模糊带来的美学提升。
在Android框架中,FLAG_BLUR_BEHIND特性的实现与SurfaceFlinger组件紧密相关。当应用此特性后,最后在WindowState中会进行读取和相关业务处理,最终通过SurfaceFlinger对图像进行实际的高斯模糊操作。在这一过程中,关键的步骤包括读取dimmer状态和根据该状态进行图像处理。进一步地,SurfaceFlinger对图层结构的调整,使得实时模糊效果得以实现。
2. Android上如何做出毛玻璃模糊的效果
上图展示了一种很典型的视觉效果——文字的背景不再是固定的,而是将底层的相应区域模糊化,好似盖了一层毛玻璃。
其原理也很简单,分为三步走:
里面涉及到的技术点有两个:
ViewTreeObserver里面有一个监听器为OnPreDrawListener
当它执行时,布局文件经过了 measured 、 laid out 、 displayed ,即将被绘制到屏幕,此时调用它的 getDrawingCache() 方法可以获得其Bitmap。完整方法如下:
方案有两种:
两种方案都可以进行对Bitmap对象的模糊处理,但当模糊半径增大时,StackBlur能够保持较好的性能,且不受Renderscript半径25px的限制。
在GitHub项目有一个项目 blurring ,其实现了StackBlur算法的Java实现版FastBlur,并给出两种方案效率对比demo。经过测试,
看起来,Renderscript的性能更好,应该是Android上对Renderscript做了优化。尽管如此,考虑到Android中渲染一帧的时间应该不超过16ms(60fps),这样的性能并不友好。 blurring 作者想出了另外一种思路:
这时候,效率提升非常明显:
生成的模糊图片当然有所不同,但是都是模糊背景,所以对用户而言没有太大差别。
好了,至此Android上制作毛玻璃背景模糊效果的技术都确定了。
我在 blurring 基础上做了封装,接口如下:
相对应类有两个:
3. android 网络获取图片从模糊到清晰
那个模糊的是先加载了一张分辨率小的预览图,然后当你点开那张预览图后,后台回去请求服务器,下载高分辨率的图片,完成后刷新imageView,就变清晰了。