鸿蒙开发-想给UI加模糊和HDR效果?uiEffect效果级联详解
本文介绍了HarmonyOS的uiEffect模块,它能为UI组件添加模糊、HDR提亮等实时视觉效果。主要包含两类效果:Filter(滤镜)和VisualEffect(视觉效果)。Filter支持模糊(blur)和HDR提亮(hdrBrightnessRatio)两种效果,可分别应用于组件背景或前景。效果可以级联叠加,按添加顺序依次生效。文章通过音乐播放器毛玻璃效果和HDR照片展示两个实际场景,演
给 UI 加点"特效":模糊、提亮、效果级联
你有没有注意到,现在很多 APP 的 UI 都有一种"毛玻璃"效果?比如 iOS 的控制中心、华为的下拉通知栏,背景是模糊的,前景内容清晰,看起来特别有层次感。
或者你有没有想过,在展示 HDR 照片时,让照片的高光区域"亮起来",比普通内容更耀眼?
HarmonyOS 的 uiEffect 模块就能帮你实现这些效果。它提供了两大类效果:Filter(滤镜) 和 VisualEffect(视觉效果),可以给 UI 组件添加模糊、提亮等各种实时效果。
导入模块
import { uiEffect } from "@kit.ArkGraphics2D";
两大效果类型
下面是 uiEffect 效果应用的整体流程:
在开始写代码之前,先理解一下 uiEffect 的两大分类:
- Filter:滤镜效果,包括模糊(blur)和 HDR 提亮(hdrBrightnessRatio)。Filter 是作用在组件的"背景"或"前景"上的。
- VisualEffect:视觉效果,目前主要是预留的扩展类。你可以通过
createEffect()创建实例,然后挂载到组件上。
这两种效果可以"级联"——也就是说,你可以在一个 Filter 或 VisualEffect 实例上叠加多个效果,它们会按顺序依次生效。
第一步:创建效果实例
创建 Filter 实例:
let filter : uiEffect.Filter = uiEffect.createFilter()
创建 VisualEffect 实例:
let visualEffect : uiEffect.VisualEffect = uiEffect.createEffect()
这两个方法返回的都是"头节点",你可以在这个实例上链式调用各种效果方法。
第二步:添加模糊效果
模糊是 Filter 最常用的效果之一。调用 blur 方法就能给组件添加模糊:
// xxx.ts
import { uiEffect } from '@kit.ArkGraphics2D';
let filter: uiEffect.Filter = uiEffect.createFilter();
filter.blur(10);
@Entry
@Component
struct UIEffectFilterExample {
build(){
Column({ space: 15 }) {
Text('UIEffectFilter').fontSize(20).width('75%').fontColor('#DCDCDC')
Image($r('app.media.foreground'))
.width(100)
.height(100)
.backgroundImage($r('app.media.background'))
.backgroundImagePosition(Alignment.Center)
.backgroundImageSize({ width: 90, height: 90 })
.backgroundFilter(filter)
}
.height('100%')
.width('100%')
}
}
这段代码做了以下几件事:
- 创建了一个 Filter 实例。
- 调用
blur(10)设置模糊半径为 10。半径越大,模糊效果越强;半径为 0 时没有模糊效果。 - 在组件上使用
.backgroundFilter(filter)将这个 Filter 应用到组件的背景上。
模糊半径的选择:
- 轻微模糊(5~15):适合做毛玻璃效果、背景虚化
- 中等模糊(20~50):适合做景深效果、焦点突出
- 强烈模糊(50+):适合做占位图、加载中的占位效果
backgroundFilter vs foregroundFilter:
.backgroundFilter(filter):效果作用在组件的背景上。比如你有一张背景图,加上模糊后,背景就变成毛玻璃了。.foregroundFilter(filter):效果作用在组件的前景内容上。比如你有一个 Text 组件,加上模糊后,文字就变模糊了。
第三步:添加 HDR 提亮效果
从 API version 24 开始,Filter 支持 HDR 提亮效果。这个效果能让组件的内容在 HDR 屏幕上显示得更亮、更耀眼。
filter.hdrBrightnessRatio(2.0)
这行代码设置了 2 倍的提亮倍数。也就是说,组件内容的亮度会被提升到 SDR 参考白亮度的 2 倍。
使用 HDR 提亮的注意事项:
- 需要权限:调用这个方法需要
ohos.permission.HDR_BRIGHTNESS权限,记得在 module.json5 里声明。 - 需要 HDR 渲染管线:提亮效果需要开启 HDR 渲染管线才能生效。如果设备硬件不支持 HDR,即使设置了也不会有效果。
- 有性能开销:HDR 提亮会带来一定的性能和功耗开销,建议只在已有 HDR 图片或视频的场景使用。
- 不建议嵌套使用:如果在多层组件上都设置了 HDR 提亮,可能会造成过曝现象。
提亮倍数的范围:
- 最小值:1.0(等于不做任何处理)
- 最大值:设备当前的最大亮度除以 SDR 参考白亮度
- 设置小于 1.0 的值时,按 1.0 处理
- 设置超过最大值的值时,按最大值处理
实际场景:做一个毛玻璃效果的音乐播放器
很多音乐播放器的背景是当前专辑封面的模糊版本。用 uiEffect 实现起来非常简单:
import { uiEffect } from '@kit.ArkGraphics2D';
// 创建模糊滤镜
let blurFilter: uiEffect.Filter = uiEffect.createFilter();
blurFilter.blur(30);
@Entry
@Component
struct MusicPlayer {
build() {
Stack() {
// 底层:专辑封面作为背景,加上模糊
Image($r('app.media.album_cover'))
.width('100%')
.height('100%')
.backgroundFilter(blurFilter)
// 上层:播放控制界面
Column() {
// 专辑封面(清晰版)
Image($r('app.media.album_cover'))
.width(250)
.height(250)
// 播放按钮等...
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
.width('100%')
.height('100%')
}
}
这里把模糊滤镜应用到背景图上,前景的专辑封面保持清晰,就能实现那种"背景虚化、前景突出"的视觉效果。
实际场景:HDR 照片展示
如果你要做一个照片展示 APP,支持 HDR 照片的"提亮"显示:
import { uiEffect } from '@kit.ArkGraphics2D';
// 创建 HDR 提亮滤镜
let hdrFilter: uiEffect.Filter = uiEffect.createFilter();
hdrFilter.hdrBrightnessRatio(2.0);
@Entry
@Component
struct PhotoViewer {
build() {
Column() {
Image($r('app.media.hdr_photo'))
.width('100%')
.height('80%')
.backgroundFilter(hdrFilter)
}
.width('100%')
.height('100%')
}
}
这样 HDR 照片在支持 HDR 的设备上就能显示出更亮、更生动的效果。
效果级联:叠加多个效果
下面是效果级联的工作原理:
uiEffect 的"级联"特性让你可以在一个 Filter 实例上叠加多个效果。比如你既要模糊又要提亮:
let filter: uiEffect.Filter = uiEffect.createFilter();
filter.blur(20);
filter.hdrBrightnessRatio(1.5);
效果会按添加的顺序依次生效。先模糊,再提亮。
小结
uiEffect 模块的核心就是两个方法:
createFilter():创建 Filter 实例,可以添加模糊和 HDR 提亮效果。createEffect():创建 VisualEffect 实例,用于扩展更多视觉效果。
把创建出来的实例通过 .backgroundFilter() 或 .foregroundFilter() 应用到组件上,就能实现实时的视觉效果。
这个模块最大的价值是让你用很少的代码就能实现复杂的视觉效果,而且这些效果是系统级别的硬件加速,性能比自己用 Canvas 画要好得多。如果你的 APP 需要毛玻璃效果、背景虚化、HDR 提亮等功能,直接用 uiEffect 就对了。
更多推荐


所有评论(0)