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
aColorFilter
设置背景图像的灰色(使用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,
...
);
}
}