Flutter 中 ColorFilter 的快速参考指南
视频
前言
在 Flutter 开发中,掌握 ColorFilter
的使用至关重要。ColorFilter
允许开发者对图像和界面元素应用颜色过滤效果,从而增强用户体验。本文为您提供了 ColorFilter
的快速参考,涵盖其用法和示例,帮助您在项目中灵活应用。通过深入理解 ColorFilter
,您将能够创建更具视觉吸引力的 Flutter 应用程序,提升整体应用效果。
参考
https://api.flutter.dev/flutter/widgets/ColorFiltered-class.html
https://api.flutter.dev/flutter/dart-ui/ColorFilter-class.html
正文
1. 滤镜
DecorationImage
类具有颜色滤镜的功能 colorFilter
属性。
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/1.webp'),
fit: BoxFit.fill,
colorFilter:
还有一个 ColorFiltered
组件将其 ColorFilter 应用到其子元素:
ColorFiltered(
colorFilter: ColorFilter.linearToSrgbGamma(),
child: Text('text'),
)
然后,我发现使用两个 Containers
仍然有意义,因为 ColorFilter
是逐像素应用的。我不完全理解那意味着什么,但我明白使用两个 Containers
更有利于性能。
无论如何, ColorFilter
方法在有几个构造函数和许多 BlendMode
值的情况下要灵活得多,因此绝对值得详细研究。
我们将使用此图像进行实验:
目前,未应用任何 ColorFilter
。
ColorFilter
有多个构造函数。
2. ColorFilter.linearToSrgbGamma()
构建一个颜色滤镜,将其应用于 RGB 通道的 sRGB 伽玛曲线。
我实在不明白上面这句话的意思。(以及下面类似的句子)。它们都来自 ColorFilter
Flutter 文档。但我们可以看到它做了什么。
colorFilter: ColorFilter.linearToSrgbGamma(),
它增加亮度。
3. ColorFilter.srgbToLinearGamma()
创建一个颜色滤镜,该滤镜对 RGB 通道应用 sRGB 伽马曲线的反函数。
colorFilter: ColorFilter.srgbToLinearGamma(),
增加对比度。或者它只是降低亮度?
4. ColorFilter.matrix 构造函数
从一个 4x5 的行主矩阵构建一个颜色滤镜。该矩阵被解释为一个 5x5 的矩阵,其中第五行是身份配置。
4.1. 透明矩阵 ColorFilter
colorFilter: getColorMatrixFilter(),
ColorFilter getColorMatrixFilter() {
// Matrix values affect the color in RGBA order
// Each row represents R, G, B, A, and offset
return ColorFilter.matrix([
1, 0, 0, 0, 0, // Red channel
0, 1, 0, 0, 0, // Green channel
0, 0, 1, 0, 0, // Blue channel
0, 0, 0, 1, 0, // Alpha channel
]);
}
它什么都不做。
4.2. 带有灰度效果的矩阵 ColorFilter
colorFilter: getGrayscaleFilter(),
ColorFilter getGrayscaleFilter() {
return ColorFilter.matrix([
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0, 0, 0, 1, 0,
]);
}
4.3. 带有棕褐色效果的矩阵 ColorFilter
colorFilter: getSepiaFilter(),
ColorFilter getSepiaFilter() {
return ColorFilter.matrix([
0.393, 0.769, 0.189, 0, 0,
0.349, 0.686, 0.168, 0, 0,
0.272, 0.534, 0.131, 0, 0,
0, 0, 0, 1, 0,
]);
}
4.4. 增加亮度的矩阵 ColorFilter
colorFilter: getBrighterFilter(),
ColorFilter getBrighterFilter() {
return ColorFilter.matrix([
1, 0, 0, 0, 63, // Add 63 to red
0, 1, 0, 0, 63, // Add 63 to green
0, 0, 1, 0, 63, // Add 63 to blue
0, 0, 0, 1, 0,
]);
}
结果类似于 ColorFilter.linearToSrgbGamma().
5. ColorFilter.mode 构造函数
模式构造函数接受两个参数:颜色和 BlendMode
。
创建一个颜色滤镜,应用第二个参数指定的混合模式。源颜色是第一个参数给出的颜色,目标颜色是正在合成的图层的颜色。
我们将使用 Colors.blue.withValues(alpha: 0.5)
作为颜色。方法 withOpacity
已被弃用(我想见见做出这个决定的超级聪明的人。我一直想知道这些人长什么样。)以上表示蓝色,不透明度为 0.5。
注意, BlendMode
的文档将被过滤的图像称为 Destination,将颜色称为 Source。
我们将按字母顺序探索 BlendMode
值(即它们在自动完成中出现的顺序)。
5.1. BlendMode.clear
丢弃源和目标,什么都不留下。
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha:0.5), BlendMode.clear),
为什么我们有一个黑屏?让我们检查代码:
class OriginalImageView extends StatelessWidget{
const OriginalImageView({super.key});
@override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/1.webp'),
fit: BoxFit.fill,
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha:0.5), BlendMode.clear),
),
),
child:
...
}
我使用 Container
并以图像作为背景。它的下方没有任何内容。在 Windows(以及 Android 和 iPhone)上,系统背景是黑色的。在网络上,它是白色的。在 Mac 上,它是浅灰色的。
由于我在 Windows 上运行此示例,因此系统背景是黑色的。
5.2. BlendMode.color
取源颜色的色相和饱和度,以及目标图像的亮度。
效果是用源颜色为目的地图像着色(高亮)。
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha:0.5), BlendMode.color),
我认为这是大多数人想要将 ColorFilter
应用于图像时所寻找的值。
5.3. BlendMode.colorBurn
将目标的逆除以源,然后对结果取逆。
反转组件意味着完全饱和的通道(不透明白色)被视为值 0.0,而通常被视为 0.0 的值(黑色,透明)被视为 1.0。
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha:0.5), BlendMode.colorBurn),
5.4. BlendMode.colorDodge
将目标除以源的倒数。
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha: 0.5), BlendMode.colorDodge),
5.5. BlendMode.darken
通过从每个颜色通道中选择最低值来合成源图像和目标图像。
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha: 0.5), BlendMode.darken),
5.6. BlendMode.difference
每个通道中,用较大的值减去较小的值。
合成黑色没有效果;合成白色会反转其他图像的颜色。
效果类似于排斥,但更严苛。
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha: 0.5), BlendMode.difference),
我会称之为“地狱效应”。
5.7. BlendMode.dst
放弃源颜色,仅绘制目标图像。
概念上,源颜色被丢弃,目的地保持不变。
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha: 0.5), BlendMode.dst),
无意义,因为它与原图相似,没有任何 ColorFilter
。但是,如果我们要动态移除 ColorFilter
,这可能会有用。
5.8. BlendMode.dstATop
将目标图像合成到源颜色上,但仅在与源重叠的地方。
这对应于“目的地在源上方”的 Porter-Duff 操作符。
这基本上是 dstOver 操作符,但输出的不透明度通道被设置为源图像的不透明度通道,而不是两个图像不透明度通道的组合。
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha: 0.5), BlendMode.dstATop),
5.9. BlendMode.dstIn
显示目标图像,但仅在两张图像重叠的地方显示。源颜色不会被渲染,它仅仅作为一个遮罩。源的颜色通道被忽略,只有不透明度起作用。
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha: 0.5), BlendMode.dstIn),
对于给定的源和目的地,结果与之前类似。
5.10. BlendMode.dstOut
显示目标图像,但仅在两个图像不重叠的地方显示。源图像不会被渲染,它仅被用作掩码。源图像的颜色通道被忽略,只有不透明度起作用。
5.11. BlendMode.dstOver
将源颜色合成在目标图像下方。
由于我们的图像不透明度为 1.0,因此 dstOver
结果是相同的图像。
5.12. BlendMode.exclusion
从两张图像的和中减去两张图像乘积的两倍。
合成黑色没有效果;合成白色会反转其他图像的颜色。
5.13. BlendMode.hardLight
调整源图像和目标图像的组件以偏向源图像,然后将它们相乘。
具体来说,如果源值较小,则将其与目标值相乘;如果目标值较小,则将目标值的倒数与源值的倒数相乘,然后对结果取倒数。
5.14. BlendMode.hue
取源颜色的色相,以及目标图像的饱和度和亮度。
效果是用源颜色为目的地图像着色。
6. 让我们动态更改 BlendMode
好的,这篇文章刚刚变得无聊了。我没有预料到有这么多的 BlendMode
值。让我们写一些代码:
class OriginalImageController extends GetxController {
var blendMode = BlendMode.clear;
@override
void onInit() async {
super.onInit();
while (true) {
for (var blendMode in BlendMode.values) {
await Future.delayed(Duration(seconds: 1));
this.blendMode = blendMode;
print(blendMode);
update();
}
}
}
}
class OriginalImageView extends GetView<OriginalImageController> {
const OriginalImageView({super.key});
@override
Widget build(BuildContext context) {
return SafeArea(
child: GetBuilder<OriginalImageController>(
builder: (controller) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/1.webp'),
fit: BoxFit.fill,
colorFilter: ColorFilter.mode(
Colors.blue.withValues(alpha: 0.5), controller.blendMode),
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
leading: CupertinoButton(
child: Icon(
Icons.chevron_left,
color: Colors.white,
size: 30,
),
onPressed: () {
Get.back();
}),
backgroundColor: Colors.transparent,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
TranslucentPanel (
width: 300,
height: 100,
child: Text(controller.blendMode.name,
style: TextStyle(color: Colors.white, fontSize: 50),),
),
],
),
),
),
);
}
),
);
}
}
结果如下:
小结
本文为您提供 Flutter 中 ColorFilter 的全面指导,涵盖基本用法、应用示例和最佳实践,帮助您快速掌握这一重要功能。
感谢阅读本文
如果有什么建议,请在评论中让我知道。我很乐意改进。
猫哥 APP
flutter 学习路径
- Flutter 优秀插件推荐
- Flutter 基础篇1 - Dart 语言学习
- Flutter 基础篇2 - 快速上手
- Flutter 实战1 - Getx Woo 电商APP
- Flutter 实战2 - 上架指南 Apple Store、Google Play
- Flutter 基础篇3 - 仿微信朋友圈
- Flutter 实战3 - 腾讯即时通讯 第一篇
- Flutter 实战4 - 腾讯即时通讯 第二篇
© 猫哥 ducafecat.com
end