制作 BoxDecoration 图片 faded/transparent
Make BoxDecoration image faded/transparent
我有以下代码片段,我想让图像褪色,这样它就不会干扰容器中的其他项目。
是否有可以实现此目的的过滤器?
child: new Card(
child: new Container(
decoration: new BoxDecoration(
color: const Color(0xff7c94b6),
image: new DecorationImage(
image: new ExactAssetImage('lib/images/pic1.jpg'),
)
)
)
)
你可以给你的 DecorationImage
一个 ColorFilter
使背景图像变成灰色(使用 saturation
滤色器)或半透明(使用 dstATop
滤色器).
此示例的代码如下。
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
小部件是另一种选择。
您也可以预先将效果应用到资产。
您可以简单地使用 Stack 小部件,并在图像上方使用一个简单的彩色容器,降低不透明度。
EG :
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/rendering.dart';
import './page2.dart';
import './page3.dart';
import './page4.dart';
void main() {
debugPaintSizeEnabled = true ;
return runApp(Start());
}
class Start extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: 'InIt',
home: Builder(builder: (context) {
return GestureDetector(
onTap: () {
return Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return Page2();
},
),
);
},
child: Scaffold(
body: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/page1.jpg'),
fit: BoxFit.fitHeight),
),
),
Container(
color: Color.fromRGBO(255, 255, 255, 0.19),
),
Container(
alignment: Alignment.center,
child: Center(
child: Text(
'LETS BE PRODUCTIVE TODAY',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 50.0,
fontFamily: 'bold',
fontWeight: FontWeight.bold,
color: Color.fromRGBO(255, 255, 255, 1)),
),
),
),
Container(
margin: EdgeInsets.only(bottom: 10.0),
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RawMaterialButton(
onPressed: () {},
constraints:
BoxConstraints.tightFor(height: 10.0, width: 10.0),
shape: CircleBorder(),
fillColor: Colors.white,
),
Page2call(),
Page3call(),
Page4call(),
],
),
)
],
),
),
);
}),
);
}
}
class Page2call extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return RawMaterialButton(
onPressed: () {
return Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return Page2();
},
),
);
},
constraints: BoxConstraints.tightFor(height: 10.0, width: 10.0),
shape: CircleBorder(),
fillColor: Colors.white,
);
}
}
class Page3call extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return RawMaterialButton(
onPressed: () {
return Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return Page3();
},
),
);
},
constraints: BoxConstraints.tightFor(height: 10.0, width: 10.0),
shape: CircleBorder(),
fillColor: Colors.white,
);
}
}
class Page4call extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return RawMaterialButton(
onPressed: () {
return Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return Page4();
},
),
);
},
constraints: BoxConstraints.tightFor(height: 10.0, width: 10.0),
shape: CircleBorder(),
fillColor: Colors.white,
);
}
}
这是一个完全实用的例子。你可以在这里增加不透明度
为了使背景更加褪色,第四个参数用于不透明度:
Container(
color: Color.fromRGBO(255, 255, 255, 0.19),
),
此方法还使您能够选择褪色滤镜的颜色。
您可以简单地使用
ColorFiltered(
colorFilter: ColorFilter.mode(Colors.black.withOpacity(0.2), BlendMode.dstATop),
child: YourWidget(),
)
对于那些想知道 性能 是否正常的人(因为图像和不透明度都是 resource-heavy 的东西) ,这是我对文档、源代码和答案的深入研究。
结论:使用DecorationImage(colorFilter: ...)
将与官方文档建议的一样快。 (但是 Opacity
、ColorFilter
小部件不是)
首先,我们应该不使用Opacity
或ColorFilter
小部件,因为它可能触发saveLayer
并且很昂贵(official doc).
相反,我们 should
Use the Opacity widget only when necessary. See the Transparent image section in the Opacity API page for an example of applying opacity directly to an image, which is faster than using the Opacity widget.
查看建议的 method,我们看到以下示例:
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
)
现在的问题是,highly-voted 答案,即下面的代码,是否与官方文档提到的 Image
小部件一样快?
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
的来源。这个构造函数会直接填充Image
.
的colorBlendMode
字段
在Image
的build
中,会直接传递给RawImage
的colorBlendMode
字段。
然后,RawImage
将创建 RenderImage
(这是一个 RenderObject)并更新 RenderImage._colorBlendMode
。
接下来,注意 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);
}
深入研究 rendering/image.dart
会发现,colorBlendMode
(并且 _colorBlendMode
除了创建此 _colorFilter
之外不会在其他地方使用。
因此,我们知道 Image.network
的两个参数最终会进入 RenderImage._colorFilter
。
确实,_colorFilter
将在 RenderImage.paint
中用作
@override
void paint(PaintingContext context, Offset offset) {
...
paintImage(
canvas: context.canvas,
rect: offset & size,
image: _image!,
colorFilter: _colorFilter,
...
);
}
所以我们知道了!它将在 paintImage
中使用,它与本地方法进行通信。难怪比Opacity
.
还快
不要回到我们的DecorationImage
。在 painting/decoration_image.dart
中,我们看到 DecorationImagePainter
:
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,
...
);
}
}
嘿嘿,一模一样!
使用Opacity class。
使其子项部分透明的小部件。
Opacity(
opacity: 0.5,
child: Image.asset('images/lion.png'),
)
我有以下代码片段,我想让图像褪色,这样它就不会干扰容器中的其他项目。 是否有可以实现此目的的过滤器?
child: new Card(
child: new Container(
decoration: new BoxDecoration(
color: const Color(0xff7c94b6),
image: new DecorationImage(
image: new ExactAssetImage('lib/images/pic1.jpg'),
)
)
)
)
你可以给你的 DecorationImage
一个 ColorFilter
使背景图像变成灰色(使用 saturation
滤色器)或半透明(使用 dstATop
滤色器).
此示例的代码如下。
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
小部件是另一种选择。
您也可以预先将效果应用到资产。
您可以简单地使用 Stack 小部件,并在图像上方使用一个简单的彩色容器,降低不透明度。
EG :
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/rendering.dart';
import './page2.dart';
import './page3.dart';
import './page4.dart';
void main() {
debugPaintSizeEnabled = true ;
return runApp(Start());
}
class Start extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: 'InIt',
home: Builder(builder: (context) {
return GestureDetector(
onTap: () {
return Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return Page2();
},
),
);
},
child: Scaffold(
body: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/page1.jpg'),
fit: BoxFit.fitHeight),
),
),
Container(
color: Color.fromRGBO(255, 255, 255, 0.19),
),
Container(
alignment: Alignment.center,
child: Center(
child: Text(
'LETS BE PRODUCTIVE TODAY',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 50.0,
fontFamily: 'bold',
fontWeight: FontWeight.bold,
color: Color.fromRGBO(255, 255, 255, 1)),
),
),
),
Container(
margin: EdgeInsets.only(bottom: 10.0),
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RawMaterialButton(
onPressed: () {},
constraints:
BoxConstraints.tightFor(height: 10.0, width: 10.0),
shape: CircleBorder(),
fillColor: Colors.white,
),
Page2call(),
Page3call(),
Page4call(),
],
),
)
],
),
),
);
}),
);
}
}
class Page2call extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return RawMaterialButton(
onPressed: () {
return Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return Page2();
},
),
);
},
constraints: BoxConstraints.tightFor(height: 10.0, width: 10.0),
shape: CircleBorder(),
fillColor: Colors.white,
);
}
}
class Page3call extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return RawMaterialButton(
onPressed: () {
return Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return Page3();
},
),
);
},
constraints: BoxConstraints.tightFor(height: 10.0, width: 10.0),
shape: CircleBorder(),
fillColor: Colors.white,
);
}
}
class Page4call extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return RawMaterialButton(
onPressed: () {
return Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return Page4();
},
),
);
},
constraints: BoxConstraints.tightFor(height: 10.0, width: 10.0),
shape: CircleBorder(),
fillColor: Colors.white,
);
}
}
这是一个完全实用的例子。你可以在这里增加不透明度 为了使背景更加褪色,第四个参数用于不透明度:
Container(
color: Color.fromRGBO(255, 255, 255, 0.19),
),
此方法还使您能够选择褪色滤镜的颜色。
您可以简单地使用
ColorFiltered(
colorFilter: ColorFilter.mode(Colors.black.withOpacity(0.2), BlendMode.dstATop),
child: YourWidget(),
)
对于那些想知道 性能 是否正常的人(因为图像和不透明度都是 resource-heavy 的东西) ,这是我对文档、源代码和答案的深入研究。
结论:使用DecorationImage(colorFilter: ...)
将与官方文档建议的一样快。 (但是 Opacity
、ColorFilter
小部件不是)
首先,我们应该不使用Opacity
或ColorFilter
小部件,因为它可能触发saveLayer
并且很昂贵(official doc).
相反,我们 should
Use the Opacity widget only when necessary. See the Transparent image section in the Opacity API page for an example of applying opacity directly to an image, which is faster than using the Opacity widget.
查看建议的 method,我们看到以下示例:
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
)
现在的问题是,highly-voted 答案,即下面的代码,是否与官方文档提到的 Image
小部件一样快?
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
的来源。这个构造函数会直接填充Image
.
colorBlendMode
字段
在Image
的build
中,会直接传递给RawImage
的colorBlendMode
字段。
然后,RawImage
将创建 RenderImage
(这是一个 RenderObject)并更新 RenderImage._colorBlendMode
。
接下来,注意 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);
}
深入研究 rendering/image.dart
会发现,colorBlendMode
(并且 _colorBlendMode
除了创建此 _colorFilter
之外不会在其他地方使用。
因此,我们知道 Image.network
的两个参数最终会进入 RenderImage._colorFilter
。
确实,_colorFilter
将在 RenderImage.paint
中用作
@override
void paint(PaintingContext context, Offset offset) {
...
paintImage(
canvas: context.canvas,
rect: offset & size,
image: _image!,
colorFilter: _colorFilter,
...
);
}
所以我们知道了!它将在 paintImage
中使用,它与本地方法进行通信。难怪比Opacity
.
不要回到我们的DecorationImage
。在 painting/decoration_image.dart
中,我们看到 DecorationImagePainter
:
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,
...
);
}
}
嘿嘿,一模一样!
使用Opacity class。 使其子项部分透明的小部件。
Opacity(
opacity: 0.5,
child: Image.asset('images/lion.png'),
)