在 Flutter 开发中,掌握 `ColorFilter` 的使用至关重要。`ColorFilter` 允许开发者对图像和界面元素应用颜色过滤效果,从而增强用户体验。本文为您提供了 `ColorFilter` 的快速参考,涵盖其用法和示例,帮助您在项目中灵活应用。通过深入理解 `ColorFilter`,您将能够创建更具视觉吸引力的 Flutter 应用程序,提升整体应用效果。

Flutter 中 ColorFilter 的快速参考指南

ColorFilter

视频

前言

原文 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 值的情况下要灵活得多,因此绝对值得详细研究。

我们将使用此图像进行实验:

img

目前,未应用任何 ColorFilter

ColorFilter 有多个构造函数。

2. ColorFilter.linearToSrgbGamma()

构建一个颜色滤镜,将其应用于 RGB 通道的 sRGB 伽玛曲线。

我实在不明白上面这句话的意思。(以及下面类似的句子)。它们都来自 ColorFilter Flutter 文档。但我们可以看到它做了什么。

colorFilter: ColorFilter.linearToSrgbGamma(),

img

它增加亮度。

3. ColorFilter.srgbToLinearGamma()

创建一个颜色滤镜,该滤镜对 RGB 通道应用 sRGB 伽马曲线的反函数。

colorFilter: ColorFilter.srgbToLinearGamma(),

img

增加对比度。或者它只是降低亮度?

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
  ]);
}

img

它什么都不做。

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,
  ]);
}

img

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,
  ]);
}

img

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,
  ]);
}

img

结果类似于 ColorFilter.linearToSrgbGamma().

5. ColorFilter.mode 构造函数

模式构造函数接受两个参数:颜色和 BlendMode

创建一个颜色滤镜,应用第二个参数指定的混合模式。源颜色是第一个参数给出的颜色,目标颜色是正在合成的图层的颜色。

我们将使用 Colors.blue.withValues(alpha: 0.5) 作为颜色。方法 withOpacity 已被弃用(我想见见做出这个决定的超级聪明的人。我一直想知道这些人长什么样。)以上表示蓝色,不透明度为 0.5。

注意, BlendMode 的文档将被过滤的图像称为 Destination,将颜色称为 Source。

img

我们将按字母顺序探索 BlendMode 值(即它们在自动完成中出现的顺序)。

5.1. BlendMode.clear

丢弃源和目标,什么都不留下。

colorFilter: ColorFilter.mode(
                  Colors.blue.withValues(alpha:0.5), BlendMode.clear),

img

为什么我们有一个黑屏?让我们检查代码:

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),

img

我认为这是大多数人想要将 ColorFilter 应用于图像时所寻找的值。

5.3. BlendMode.colorBurn

将目标的逆除以源,然后对结果取逆。

反转组件意味着完全饱和的通道(不透明白色)被视为值 0.0,而通常被视为 0.0 的值(黑色,透明)被视为 1.0。

colorFilter: ColorFilter.mode(
               Colors.blue.withValues(alpha:0.5), BlendMode.colorBurn),

img

5.4. BlendMode.colorDodge

将目标除以源的倒数。

colorFilter: ColorFilter.mode(
                Colors.blue.withValues(alpha: 0.5), BlendMode.colorDodge),

img

5.5. BlendMode.darken

通过从每个颜色通道中选择最低值来合成源图像和目标图像。

colorFilter: ColorFilter.mode(
                Colors.blue.withValues(alpha: 0.5), BlendMode.darken),

img

5.6. BlendMode.difference

每个通道中,用较大的值减去较小的值。

合成黑色没有效果;合成白色会反转其他图像的颜色。

效果类似于排斥,但更严苛。

colorFilter: ColorFilter.mode(
        Colors.blue.withValues(alpha: 0.5), BlendMode.difference),

img

我会称之为“地狱效应”。

5.7. BlendMode.dst

放弃源颜色,仅绘制目标图像。

概念上,源颜色被丢弃,目的地保持不变。

colorFilter: ColorFilter.mode(
                Colors.blue.withValues(alpha: 0.5), BlendMode.dst),

img

无意义,因为它与原图相似,没有任何 ColorFilter 。但是,如果我们要动态移除 ColorFilter ,这可能会有用。

5.8. BlendMode.dstATop

将目标图像合成到源颜色上,但仅在与源重叠的地方。

这对应于“目的地在源上方”的 Porter-Duff 操作符。

这基本上是 dstOver 操作符,但输出的不透明度通道被设置为源图像的不透明度通道,而不是两个图像不透明度通道的组合。

colorFilter: ColorFilter.mode(
                Colors.blue.withValues(alpha: 0.5), BlendMode.dstATop),

img

5.9. BlendMode.dstIn

显示目标图像,但仅在两张图像重叠的地方显示。源颜色不会被渲染,它仅仅作为一个遮罩。源的颜色通道被忽略,只有不透明度起作用。

colorFilter: ColorFilter.mode(
                Colors.blue.withValues(alpha: 0.5), BlendMode.dstIn),

img

对于给定的源和目的地,结果与之前类似。

5.10. BlendMode.dstOut

显示目标图像,但仅在两个图像不重叠的地方显示。源图像不会被渲染,它仅被用作掩码。源图像的颜色通道被忽略,只有不透明度起作用。

img

5.11. BlendMode.dstOver

将源颜色合成在目标图像下方。

由于我们的图像不透明度为 1.0,因此 dstOver 结果是相同的图像。

img

5.12. BlendMode.exclusion

从两张图像的和中减去两张图像乘积的两倍。

合成黑色没有效果;合成白色会反转其他图像的颜色。

img

5.13. BlendMode.hardLight

调整源图像和目标图像的组件以偏向源图像,然后将它们相乘。

具体来说,如果源值较小,则将其与目标值相乘;如果目标值较小,则将目标值的倒数与源值的倒数相乘,然后对结果取倒数。

img

5.14. BlendMode.hue

取源颜色的色相,以及目标图像的饱和度和亮度。

效果是用源颜色为目的地图像着色。

img

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),),
                    ),
                  ],
                ),
              ),
            ),
          );
        }
      ),
    );
  }
}

结果如下:

img

小结

本文为您提供 Flutter 中 ColorFilter 的全面指导,涵盖基本用法、应用示例和最佳实践,帮助您快速掌握这一重要功能。

感谢阅读本文

如果有什么建议,请在评论中让我知道。我很乐意改进。


猫哥 APP

flutter 学习路径


© 猫哥 ducafecat.com

end