sid*_*sid 10 flutter mix-blend-mode flutter-image
我尝试过似乎仅适用于颜色的混合模式,即 colorblendmode。有什么方法可以实现CSS的mix-blend-mode吗?
Stack(
children: <Widget>[
Image.asset(
"asset/text.PNG",
height: double.maxFinite,
width: double.maxFinite,
fit: BoxFit.fitHeight,
color: Colors.red,
colorBlendMode: BlendMode.multiply,
),
Image.asset("asset/face.jpg",
width: double.maxFinite,
fit: BoxFit.fitHeight,
color: Colors.red,
colorBlendMode: BlendMode.multiply),
],
),
Run Code Online (Sandbox Code Playgroud)
这会导致类似: 上面代码的输出
使用 RenderProxyBox 和一些绘画,我能够在 CSS 网站上重新创建确切的示例,而无需在 Flutter 代码中异步加载图像。
使用 CSS 的图像(左)与使用 Flutter 的图像(右)。
首先,创建了一个 BlendMask SingleChildRenderObject,它创建了一个名为 RenderBlendMask 的 RenderProxyBox 渲染对象。使用 BlendMode 和不透明度绘制子项。
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
class BlendMask extends SingleChildRenderObjectWidget {
final BlendMode blendMode;
final double opacity;
BlendMask({
@required this.blendMode,
this.opacity = 1.0,
Key key,
Widget child,
}) : super(key: key, child: child);
@override
RenderObject createRenderObject(context) {
return RenderBlendMask(blendMode, opacity);
}
@override
void updateRenderObject(BuildContext context, RenderBlendMask renderObject) {
renderObject.blendMode = blendMode;
renderObject.opacity = opacity;
}
}
class RenderBlendMask extends RenderProxyBox {
BlendMode blendMode;
double opacity;
RenderBlendMask(this.blendMode, this.opacity);
@override
void paint(context, offset) {
context.canvas.saveLayer(
offset & size,
Paint()
..blendMode = blendMode
..color = Color.fromARGB((opacity * 255).round(), 255, 255, 255));
super.paint(context, offset);
context.canvas.restore();
}
}
Run Code Online (Sandbox Code Playgroud)
现在要混合两个小部件(不限于图像),只需使用堆栈将要混合的小部件添加到另一个小部件上方,然后将其包裹在您的 BlendMode 中。
class ImageMixer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox.expand(
child: Stack(
children: [
SizedBox.expand(
child: Image.asset(
'images/sky.jpg',
),
),
BlendMask(
opacity: 1.0,
blendMode: BlendMode.softLight,
child: SizedBox.expand(
child: Image.asset(
'images/monkey.jpg',
),
),
),
],
)),
);
}
}
Run Code Online (Sandbox Code Playgroud)
这产生了上面的图像,它的工作原理与 CSS 示例完全相同。
试试ShaderMask。
混合模式
使用示例:
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: SafeArea(
child: MyHomePage(),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<ui.Image> loadUiImage(String imageAssetPath) async {
final data = await rootBundle.load(imageAssetPath);
final completer = Completer<ui.Image>();
ui.decodeImageFromList(Uint8List.view(data.buffer), completer.complete);
return completer.future;
}
@override
Widget build(BuildContext context) {
return FutureBuilder<ui.Image>(
future: loadUiImage('assets/cara_img.png'),
builder: (context, img) {
return img.hasData
? ShaderMask(
blendMode: BlendMode.colorDodge,
shaderCallback: (bounds) => ImageShader(
img.data,
TileMode.clamp,
TileMode.clamp,
Matrix4.identity().storage,
),
child: Image.asset('assets/code.png'),
)
: Container(
color: Colors.red,
height: 100,
width: 100,
child: Text('loading'),
);
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1918 次 |
| 最近记录: |