hi,粉丝朋友们!
今天有个学员朋友,问到了一个高斯模糊相关问题,这个高斯模糊相关的需求我相对还是比较熟悉,下面来重点讲解一下新版本高斯模糊相关的实现。
更多framework干货知识手把手教学

Log.i("qq群",“422901085”);

1、高斯模糊应用场景

状态栏下拉时候可以看到桌面的画面作为背景,但是这个时候桌面的画面却是被高斯模糊的,这样给人交互体验上就有一个很大提升,美观层度和主次分明,就像拍照时候的人物一样,会把背景等模糊,把人物作为重点。

2、高斯模糊实现方案

方案1 截图这种属于最为常规的方案,以前都采用该方案,主要实现原理也很简单:
对背景截图 —》 对截图bitmap进行高斯模糊图像处理 —》把处理后的bitmap作为背景展示
优点:方案简单,属于所有模糊等都是自己控制,控制灵活性大
缺点:因为截图,所以没办法搞成实时模糊,实现功能修改逻辑较多

方案2 这个是新版本android才有的自带方法,它的实现原理,对某一个window进行flag的设置,如果设置了FLAG_BLUR_BEHIND,那么它后面的window层就会被设置成模糊,属于surfaceflinger层面实现了,在渲染时候layer处理,这个模糊属于实时的,即后面画面哪怕在动,高斯模糊也跟着动
优点:属于系统提供的接口相关,简单设置即可以,不需要自己额外操作,可以实时模糊

缺点:因为操作对象是window,只是窗口下面的会被模糊,导致一些窗口切换场景可能会有bug
下面我们就来重点介绍一下

3、重点介绍新方案2 FLAG_BLUR_BEHIND 使用

frameworks/base/core/java/android/view/WindowManager.java

   /** Window flag: enable blur behind for this window. */public static final int FLAG_BLUR_BEHIND        = 0x00000004;

这个FLAG_BLUR_BEHIND属于LayoutParams

注释就是说FLAG_BLUR_BEHIND就会让在该window下面的window进行模糊
具体如果要使用:
其实就是对window的LayoutParams设置这个flag

 getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

同时还有另一个方法setBlurBehindRadius

 public void setBlurBehindRadius(@IntRange(from = 0) int blurBehindRadius) {mBlurBehindRadius = blurBehindRadius;}

大家都知道高斯模糊都有一个模糊滤镜,这代表模糊的程度,一般mBlurBehindRadius越大模糊层度越厉害。代码如下:

 @Overrideprotected void onResume() {super.onResume();getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,WindowManager.LayoutParams.FLAG_BLUR_BEHIND);getWindow().getAttributes().setBlurBehindRadius(100);//设置大一点为100,看的明显}

模糊前后效果对比如下:
模糊前:

模糊后:

4、原理源码分析

设置了FLAG_BLUR_BEHIND后,最后在WindowState会进行读取和相关业务处理:
frameworks/base/services/core/java/com/android/server/wm/WindowState.java

private boolean shouldDrawBlurBehind() {return (mAttrs.flags & FLAG_BLUR_BEHIND) != 0&& mWmService.mBlurController.getBlurEnabled();}

然后在applyDims方法中根据这个进行相关的执行:

private void applyDims() {if (!mAnimatingExit && mAppDied) {mIsDimming = true;getDimmer().dimAbove(getSyncTransaction(), this, DEFAULT_DIM_AMOUNT_DEAD_WINDOW);} else if (((mAttrs.flags & FLAG_DIM_BEHIND) != 0 || shouldDrawBlurBehind())&& isVisibleNow() && !mHidden) {// Only show the Dimmer when the following is satisfied:// 1. The window has the flag FLAG_DIM_BEHIND or blur behind is requested// 2. The WindowToken is not hidden so dims aren't shown when the window is exiting.// 3. The WS is considered visible according to the isVisible() method// 4. The WS is not hidden.mIsDimming = true;final float dimAmount = (mAttrs.flags & FLAG_DIM_BEHIND) != 0 ? mAttrs.dimAmount : 0;final int blurRadius = shouldDrawBlurBehind() ? mAttrs.getBlurBehindRadius() : 0;getDimmer().dimBelow(getSyncTransaction(), this, dimAmount, blurRadius);}}

下面来看这个 getDimmer().dimBelow方法执行:

 void dimBelow(SurfaceControl.Transaction t, WindowContainer container, float alpha,int blurRadius) {dim(t, container, -1, alpha, blurRadius);//调用dim方法}private void dim(SurfaceControl.Transaction t, WindowContainer container, int relativeLayer,float alpha, int blurRadius) {final DimState d = getDimState(container);//这里比较关键需要创建对应EffectLayerif (d == null) {return;}if (container != null) {// The dim method is called from WindowState.prepareSurfaces(), which is always called// in the correct Z from lowest Z to highest. This ensures that the dim layer is always// relative to the highest Z layer with a dim.t.setRelativeLayer(d.mDimLayer, container.getSurfaceControl(), relativeLayer);} else {t.setLayer(d.mDimLayer, Integer.MAX_VALUE);}t.setAlpha(d.mDimLayer, alpha);t.setBackgroundBlurRadius(d.mDimLayer, blurRadius);//对这个图层进行BlurRadius设置d.mDimming = true;}

这里来重点看看getDimState看看是怎么创建的:

 /*** Retrieve the DimState, creating one if it doesn't exist.*/private DimState getDimState(WindowContainer container) {if (mDimState == null) {try {final SurfaceControl ctl = makeDimLayer();//这里又调用makeDimLayer创建mDimState = new DimState(ctl);/*** See documentation on {@link #dimAbove} to understand lifecycle management of* Dim's via state resetting for Dim's with containers.*/if (container == null) {mDimState.mDontReset = true;}} catch (Surface.OutOfResourcesException e) {Log.w(TAG, "OutOfResourcesException creating dim surface");}}mLastRequestedDimContainer = container;return mDimState;}private SurfaceControl makeDimLayer() {return mHost.makeChildSurface(null).setParent(mHost.getSurfaceControl())//这里host就是我们activity的task.setColorLayer()//注意是这种类型的layer.setName("Dim Layer for - " + mHost.getName()).setCallsite("Dimmer.makeDimLayer").build();}

上面代码层面分析后,来看看SurfaceFlinger相关图层有啥变化

android13 FLAG_BLUR_BEHIND 壁纸高斯模糊,毛玻璃背景方案设计-千里马framework实战相关推荐

  1. Android 10.0 Launcher3双层(抽屉)高斯模糊(毛玻璃)背景功能的实现

    1.概述 在进行定制开发的功能需求方面,Launcher3的需求也挺多的,单双层抽屉高斯模糊毛玻璃背景功能也是一个需求功能,最近按照功能需求来开发 双层抽屉高斯模糊毛玻璃效果背景的功能 效果图如图: ...

  2. 动态毛玻璃特效html,实现div毛玻璃背景

    毛玻璃效果 ios里毛玻璃效果的使用非常多,本文介绍一个实现div毛玻璃背景的方法 CSS3 Filter CSS3的Filter主要用在图像的特效处理上,默认值为none,还有以下备选项: 1.gr ...

  3. android高仿微信聊天页面,Android 高仿微信语音聊天页面高斯模糊(毛玻璃效果)

    目前的应用市场上,使用毛玻璃效果的APP随处可见,比如用过微信语音聊天的人可以发现,语音聊天页面就使用了高斯模糊效果. 先看下效果图: 仔细观察上图,我们可以发现,背景图以用户头像为模板,对其进行了高 ...

  4. 实现div毛玻璃背景

    毛玻璃效果 ios里毛玻璃效果的使用非常多,本文介绍一个实现div毛玻璃背景的方法 CSS3 Filter CSS3的Filter主要用在图像的特效处理上,默认值为none,还有以下备选项: 1.gr ...

  5. html使背景图片毛玻璃效果,vue实现毛玻璃背景图片效果

    vue实现毛玻璃背景图片 效果 代码 round width="80px" height="80px" :src="head_img" cl ...

  6. Python——实现Windows桌面壁纸和bing背景的同步

    目的 实现Windows桌面壁纸和bing背景的同步 如何实现 requests(获取url) json(解析对象) os.path(设置图片保存路径以及日志信息) ctypes(设置Windows壁 ...

  7. php文件怎么做壁纸,自动调取在线壁纸作为网站背景(PHP接口源码)+赠送三个壁纸接口...

    [PHP] 纯文本查看 复制代码<?php /* 功能:自动调取壁纸作为网站背景 开发时间:2017年7月4日 应用案例:https://www.68xi.cn/search/ 分享三个在线壁纸 ...

  8. VTK:背景渐变BackgroundGradient用法实战

    VTK:背景渐变BackgroundGradient用法实战 程序输出 程序完整源代码 程序输出 程序完整源代码 #include <vtkActor.h> #include <vt ...

  9. VTK:背景颜色BackgroundColor用法实战

    VTK:背景颜色BackgroundColor用法实战 程序输出 程序完整源代码 程序输出 程序完整源代码 #include <vtkActor.h> #include <vtkNe ...

最新文章

  1. Linux_正则表达式
  2. fibonacci climbing-stairs
  3. mysql关系数据库引擎_MySQL数据库引擎详解
  4. 前端学习(2859):简单秒杀系统学习之前端界面布局
  5. 常用转义符的使用 java 0133
  6. 如何通过虚拟私有云保障服务安全【华为云分享】
  7. java访问方法修饰词四个_java中的四个修饰词(访问权限)
  8. c语言禁止优化某段代码,C语言优化小技巧
  9. 在Eclipse中使用SDK中的@hide函数
  10. 卡特兰数-两个经典做法
  11. php记录sql语句,sql语句记录
  12. MATLAB APP设计工具
  13. PS混合模式图文详解
  14. 波士顿地区Airbnb价格预测Project (一)
  15. [Android] 代码获取手机系统类型(小米MIUI、华为EMUI、魅族FLYME)
  16. VS2022 MAUI Hello World——Windows平台及Android平台效果
  17. IBM MQ常用命令
  18. 408,你可敬的对手!
  19. jenkins 邮件配置展示change信息
  20. Startup通过3D打印制造更便宜、更轻的火箭 | 广东省智能创新协会

热门文章

  1. Apache(阿帕奇)基本操作
  2. 神经网络教材推荐,神经网络经典书籍
  3. 维基百科里 的intj  直接复制的html .还是有点乱
  4. SGame 新加进程(2)
  5. jtl如何转换成html,Jmeter根据日期生成JTL和HTML报告
  6. 重庆永川实现停车自由 百度地图助力打造西部智能交通新样板
  7. mapboxGL2离线化应用
  8. 我和这对最近融资2.32亿美元的创业夫妻档聊了聊 ...
  9. Eternalblue-2.2.0 shellcode 分析
  10. 因为计算机安装了更新i,电脑安装iTunes时提示这台电脑已安装了更高版本的解决方法图文教程...