Dart 使盒子装饰图像褪色/透明

Dart 使盒子装饰图像褪色/透明,dart,flutter,Dart,Flutter,我有下面的代码片段,我想使图像褪色,这样它就不会干扰容器中的其他项目。 是否有一个过滤器可以实现这一点 child: new Card( child: new Container( decoration: new BoxDecoration( color: const Color(0xff7c94b6), image: new DecorationImage( image: new ExactAssetImage('lib/images

我有下面的代码片段,我想使图像褪色,这样它就不会干扰容器中的其他项目。 是否有一个过滤器可以实现这一点

child: new Card(
  child: new Container(
    decoration: new BoxDecoration(
      color: const Color(0xff7c94b6),
        image: new DecorationImage(
          image: new ExactAssetImage('lib/images/pic1.jpg'),
             )
           )
     )
   )

您可以给您的
DecorationImage
a
ColorFilter
设置背景图像的灰色(使用
saturation
ColorFilter)或半透明(使用
dstoop
ColorFilter)

下面是这个例子的代码

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) => new Scaffold(
    appBar: new AppBar(
      title: new Text('Grey Example'),
    ),
    body: new Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        new Card(
          child: new Container(
            child: new Text(
              'Hello world',
              style: Theme.of(context).textTheme.display4
            ),
            decoration: new BoxDecoration(
              color: const Color(0xff7c94b6),
              image: new DecorationImage(
                fit: BoxFit.cover,
                colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.2), BlendMode.dstATop),
                image: new NetworkImage(
                  'http://www.allwhitebackground.com/images/2/2582-190x190.jpg',
                ),
              ),
            ),
          ),
        ),
      ],
    ),
  );
}
Opacity
小部件是另一个选项


您还可以将效果预应用于资产。

您只需使用堆栈小部件,并在图像上方使用简单的彩色容器,降低不透明度

例如:

这种方法还使你能够选择褪色滤光片的颜色

您只需使用

ColorFiltered(
  colorFilter: ColorFilter.mode(Colors.black.withOpacity(0.2), BlendMode.dstATop),
  child: YourWidget(),
) 
对于那些想知道性能是否正常的人(因为图像和不透明度都是资源密集型的东西),下面是我对文档和源代码的挖掘以及答案

结论:使用
DecorationImage(colorFilter:…)
将和官方文件建议的一样快。(但是,
Opacity
ColorFilter
小部件不是)

首先,我们不应该使用
Opacity
ColorFilter
小部件,因为它可能会触发
saveLayer
,而且价格昂贵

相反,我们

仅在必要时使用“不透明度”小部件。有关将不透明度直接应用于图像的示例,请参见“不透明度API”页面中的“透明图像”部分,这比使用“不透明度”小部件更快

查看建议的示例,我们可以看到以下示例:

Image.network(
  'https://raw.githubusercontent.com/flutter/assets-for-api-docs/master/packages/diagrams/assets/blend_mode_destination.jpeg',
  color: Color.fromRGBO(255, 255, 255, 0.5),
  colorBlendMode: BlendMode.modulate
)
现在,问题是,高投票率的答案,即下面的代码,是否与官方文档提到的
Image
widget一样快

Container(
  child: Text('hi'),
  decoration: BoxDecoration(
    color: const Color(0xff7c94b6),
    image: new DecorationImage(
      fit: BoxFit.cover,
      colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.2), BlendMode.dstATop),
      image: new NetworkImage(
        'http://www.allwhitebackground.com/images/2/2582-190x190.jpg',
      ),
    ),
  ),
),
要回答这个问题,让我们看看
Image.network
的源代码。此构造函数将直接填充
图像的
colorBlendMode
字段

Image
build
中,它将直接传递到
RawImage
colorBlendMode
字段

然后,
RawImage
将创建
RenderImage
(这是一个RenderObject)并更新
RenderImage

接下来,请注意RenderImage是如何处理此问题的-

  BlendMode? _colorBlendMode;
  set colorBlendMode(BlendMode? value) {
    if (value == _colorBlendMode)
      return;
    _colorBlendMode = value;
    _updateColorFilter();
    markNeedsPaint();
  }

  ...

  /// If non-null, this color is blended with each image pixel using [colorBlendMode].
  Color? get color => _color;
  Color? _color;
  set color(Color? value) {
    if (value == _color)
      return;
    _color = value;
    _updateColorFilter();
    markNeedsPaint();
  }

  ...

  ColorFilter? _colorFilter;
  void _updateColorFilter() {
    if (_color == null)
      _colorFilter = null;
    else
      _colorFilter = ColorFilter.mode(_color!, _colorBlendMode ?? BlendMode.srcIn);
  }
深入研究
渲染/image.dart
将显示,
colorBlendMode
(和
\u colorBlendMode
将不会在其他地方使用,除非用于创建此
\u colorFilter

因此,我们知道
Image.network
的两个参数最终将进入
渲染

实际上,该
\u colorFilter
将在
渲染中使用

  @override
  void paint(PaintingContext context, Offset offset) {
    ...
    paintImage(
      canvas: context.canvas,
      rect: offset & size,
      image: _image!,
      colorFilter: _colorFilter,
      ...
    );
  }
所以我们知道它!它将用于与本机方法通信的
paintImage
。难怪它比
Opacity
更快

不要返回到我们的
装饰图像
。在
绘制/装饰图像。dart
,我们看到
装饰图像绘制者

class DecorationImagePainter {
  DecorationImagePainter._(this._details, ...);

  final DecorationImage _details;

  void paint(Canvas canvas, Rect rect, Path? clipPath, ImageConfiguration configuration) {
    ...
    paintImage(
      canvas: canvas,
      rect: rect,
      image: _image!.image,
      colorFilter: _details.colorFilter,
      ...
    );
  }
}

嘿,这是完全一样的!

不透明度小部件似乎会影响整个容器的内容,这不是我想要的。我已经使用了预应用效果。如何使用ColorFilter使其透明?将颜色设置为灰色似乎会覆盖blendmode可能具有的任何效果。谢谢。对于不透明度,您可以使用我更新了我的答案,为颜色过滤器方法提供了一个代码示例。
  @override
  void paint(PaintingContext context, Offset offset) {
    ...
    paintImage(
      canvas: context.canvas,
      rect: offset & size,
      image: _image!,
      colorFilter: _colorFilter,
      ...
    );
  }
class DecorationImagePainter {
  DecorationImagePainter._(this._details, ...);

  final DecorationImage _details;

  void paint(Canvas canvas, Rect rect, Path? clipPath, ImageConfiguration configuration) {
    ...
    paintImage(
      canvas: canvas,
      rect: rect,
      image: _image!.image,
      colorFilter: _details.colorFilter,
      ...
    );
  }
}