Flutter图像洪水填充插件floodfill_image的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter图像洪水填充插件floodfill_image的使用

Flood Fill Image

Version GitHub license Support

Flutter widget 可以在提供的图像上使用油漆桶功能,采用 J. Dunlap 的队列线性洪水填充算法。更多详情请参阅我的博客:Flood Fill in Flutter

如果你觉得这个库有用,请在 pub dev 上点赞👍 或者在 github 上给仓库加星⭐。

demo dog gif

使用方法

FloodFillImage(
    imageProvider: AssetImage("assets/dog.jpg"),
    fillColor: Colors.amber,
    avoidColor: [Colors.transparent, Colors.black],
)

参数

名称 类型 描述
imageProvider ImageProvider 通过 ImageProvider 显示的图像。
你可以使用 AssetImageNetworkImage
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:uiImage
注意:触摸坐标相对于图像尺寸。
onFloodFillEnd Function(Image image) 当洪水填充结束时的回调函数,返回来自 dart:uiImage

完整示例代码

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 支持作者。

Buy Me A Coffee


更多关于Flutter图像洪水填充插件floodfill_image的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于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),
            ),
          ),
      ],
    );
  }
}

注意

  1. floodFill函数是假设存在的,实际上floodfill_image插件可能提供的是不同的API。你需要参考插件的官方文档来调整代码。
  2. 由于floodfill_image插件的具体API和实现可能有所不同,上述代码中的floodFill函数需要根据插件的实际API进行替换或调整。
  3. 示例中的_performFloodFill方法展示了如何从图像中获取像素数据,执行洪水填充,并返回新的图像数据。实际使用中,你需要根据插件的API来修改这部分代码。
  4. 确保你的Flutter项目中有assets/sample_image.png这张图片,或者替换为你自己的图片路径。

由于floodfill_image插件的具体实现细节和API可能有所不同,强烈建议你查阅插件的官方文档和示例代码,以获得更准确的使用指南。

回到顶部