Flutter图像洪水填充插件floodfill_image的使用
Flutter图像洪水填充插件floodfill_image的使用
Flood Fill Image
Flutter widget 可以在提供的图像上使用油漆桶功能,采用 J. Dunlap 的队列线性洪水填充算法。更多详情请参阅我的博客:Flood Fill in Flutter
如果你觉得这个库有用,请在 pub dev 上点赞👍 或者在 github 上给仓库加星⭐。
使用方法
FloodFillImage(
imageProvider: AssetImage("assets/dog.jpg"),
fillColor: Colors.amber,
avoidColor: [Colors.transparent, Colors.black],
)
参数
名称 | 类型 | 描述 |
---|---|---|
imageProvider |
ImageProvider | 通过 ImageProvider 显示的图像。 你可以使用 AssetImage 或 NetworkImage 。 |
fillColor |
Color | 用于填充区域的颜色。 |
isFillActive |
bool | 如果你想要禁用触摸填充功能,设置为 false 。默认值是 true 。 |
avoidColor |
List<Color> | 确定哪些颜色需要避免在触摸时被填充。 注意:应用最近的颜色阴影。 |
tolerance |
int | 设置填充值的容差范围从 0 到 100。 默认值是 8。 |
width |
int | 图像宽度。如果提供了父级小部件宽度并且小于图像宽度,则优先考虑父级小部件宽度。 |
height |
int | 图像高度。如果提供了父级小部件高度并且小于图像高度,则优先考虑父级小部件高度。 |
alignment |
AlignmentGeometry | 图像对齐方式。 |
loadingWidget |
Widget | 在初始化过程中处理图像时显示的小部件。 默认使用 CircularProgressIndicator 。 |
onFloodFillStart |
Function(Offset position,Image image) | 当洪水填充开始时的回调函数,返回触摸位置和来自 dart:ui 的 Image 。注意:触摸坐标相对于图像尺寸。 |
onFloodFillEnd |
Function(Image image) | 当洪水填充结束时的回调函数,返回来自 dart:ui 的 Image 。 |
完整示例代码
import 'package:floodfill_image/floodfill_image.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flood Fill Image Example',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flood Fill Image Example'),
);
}
}
class MyHomePage extends StatefulWidget {
final String? title;
MyHomePage({Key? key, this.title}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Color _fillColor = Colors.amber;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title!),
),
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloodFillImage(
imageProvider: AssetImage("assets/dog.jpg"),
fillColor: _fillColor,
avoidColor: [Colors.transparent, Colors.black],
tolerance: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextButton(
onPressed: () {
setState(() {
_fillColor = Colors.brown;
});
},
child: Text("Brown", style: TextStyle(color: Colors.black)),
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.brown)),
),
TextButton(
onPressed: () {
setState(() {
_fillColor = Colors.amber;
});
},
child: Text("Amber", style: TextStyle(color: Colors.black)),
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.amber)),
),
TextButton(
onPressed: () {
setState(() {
_fillColor = Colors.cyan;
});
},
child: Text("Cyan", style: TextStyle(color: Colors.black)),
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.cyan)),
),
],
)
],
),
),
),
);
}
}
License
MIT License,详见 LICENSE.md 文件。
支持作者
如果你喜欢这个插件,可以通过 Buy Me A Coffee 支持作者。
更多关于Flutter图像洪水填充插件floodfill_image的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图像洪水填充插件floodfill_image的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用floodfill_image
插件来进行图像洪水填充的一个示例。floodfill_image
插件允许你在图像上执行洪水填充操作,通常用于选择并填充图像的某个区域。
首先,确保你已经在pubspec.yaml
文件中添加了floodfill_image
依赖:
dependencies:
flutter:
sdk: flutter
floodfill_image: ^最新版本号 # 请替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,我们可以编写一个Flutter应用来使用这个插件。以下是一个完整的示例代码:
import 'package:flutter/material.dart';
import 'package:floodfill_image/floodfill_image.dart';
import 'dart:ui' as ui;
import 'dart:typed_data';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flood Fill Image Example'),
),
body: FloodFillExample(),
),
);
}
}
class FloodFillExample extends StatefulWidget {
@override
_FloodFillExampleState createState() => _FloodFillExampleState();
}
class _FloodFillExampleState extends State<FloodFillExample> {
Uint8List? _imageBytes;
Uint8List? _filledImageBytes;
Offset? _seedPoint;
@override
void initState() {
super.initState();
_loadImage('assets/sample_image.png'); // 请确保在assets文件夹中有这张图片
}
Future<void> _loadImage(String assetPath) async {
ByteData data = await rootBundle.load(assetPath);
Uint8List bytes = data.buffer.asUint8List();
setState(() {
_imageBytes = bytes;
});
}
Future<void> _performFloodFill(BuildContext context, Offset point) async {
if (_imageBytes == null) return;
final ui.Codec codec = await ui.instantiateImageCodec(_imageBytes!);
final ui.FrameInfo frameInfo = await codec.getNextFrame();
final ui.Image image = frameInfo.image;
final int fillColor = 0xFFFFFFFF; // 白色填充
final int tolerance = 50; // 容忍度
final Uint8List filledImageBytes = await floodFill(
image,
point,
fillColor: fillColor,
tolerance: tolerance,
);
setState(() {
_filledImageBytes = filledImageBytes;
_seedPoint = point;
});
Navigator.of(context).pop();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: _imageBytes != null
? Image.memory(_imageBytes!)
: Center(child: CircularProgressIndicator()),
),
ElevatedButton(
onPressed: () async {
final renderBox = context.findRenderObject() as RenderBox;
final size = renderBox.size;
final Offset tapPosition = await showModalBottomSheet<Offset>(
context: context,
builder: (BuildContext context) {
return GestureDetector(
onTapDown: (TapDownDetails details) {
final RenderBox box = context.findRenderObject() as RenderBox;
final Offset tapPosition = box.globalToLocal(details.globalPosition);
Navigator.of(context).pop(tapPosition);
},
child: Container(
height: size.height * 0.7,
color: Colors.transparent,
child: Image.memory(_imageBytes!),
),
);
},
);
if (tapPosition != null) {
_performFloodFill(context, tapPosition);
}
},
child: Text('Perform Flood Fill'),
),
if (_filledImageBytes != null)
Expanded(
child: Image.memory(_filledImageBytes!),
),
if (_seedPoint != null)
Container(
color: Colors.transparent,
alignment: Alignment.topRight,
padding: EdgeInsets.all(16.0),
child: Text(
'Seed Point: ${_seedPoint!.toString()}',
style: TextStyle(color: Colors.white),
),
),
],
);
}
}
注意:
floodFill
函数是假设存在的,实际上floodfill_image
插件可能提供的是不同的API。你需要参考插件的官方文档来调整代码。- 由于
floodfill_image
插件的具体API和实现可能有所不同,上述代码中的floodFill
函数需要根据插件的实际API进行替换或调整。 - 示例中的
_performFloodFill
方法展示了如何从图像中获取像素数据,执行洪水填充,并返回新的图像数据。实际使用中,你需要根据插件的API来修改这部分代码。 - 确保你的Flutter项目中有
assets/sample_image.png
这张图片,或者替换为你自己的图片路径。
由于floodfill_image
插件的具体实现细节和API可能有所不同,强烈建议你查阅插件的官方文档和示例代码,以获得更准确的使用指南。