Flutter文本区域检测插件flutter_text_detect_area的使用

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

Flutter文本区域检测插件flutter_text_detect_area的使用

flutter_text_detect_area 是一个用于在Flutter应用中通过选择图像或实时摄像头中的特定区域来识别文本的插件。用户可以通过拖动、移动或缩放选择器来选择图像的特定区域,并进行文本识别。该插件还支持单次识别和多次识别,以及启用或禁用图像交互。

安装

  1. 添加依赖项

    pubspec.yaml 文件中添加 flutter_text_detect_area 依赖项:

    dependencies:
      flutter_text_detect_area: <latest-version>
    

    请确保使用最新版本。

  2. 导入包

    在 Dart 文件中导入 flutter_text_detect_area 包:

    import 'package:flutter_text_detect_area/flutter_text_detect_area.dart';
    

示例代码

以下是一个完整的示例代码,展示了如何使用 flutter_text_detect_area 插件来选择图像区域并进行文本识别。

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter_text_detect_area/flutter_text_detect_area.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Text Detect Area',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        useMaterial3: false,
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Text Detect Area'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String detectedValue = "";
  String cameraDetectedValue = "";
  bool isDetectOnce = true;
  bool enableImageInteractions = true;
  TextRecognitionScript initialRecognitionScript = TextRecognitionScript.latin;

  [@override](/user/override)
  Widget build(BuildContext context) {
    void setDetectOnce(bool isDetectOnce) {
      setState(() {
        detectedValue = "";
        this.isDetectOnce = isDetectOnce;
      });
    }

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(20),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              ListTile(
                title: const Text('单次检测'),
                leading: Radio<bool>(
                  value: true,
                  groupValue: isDetectOnce,
                  onChanged: setDetectOnce,
                ),
              ),
              ListTile(
                title: const Text('多次检测'),
                leading: Radio<bool>(
                  value: false,
                  groupValue: isDetectOnce,
                  onChanged: setDetectOnce,
                ),
              ),
              ListTile(
                title: Text(
                    "${enableImageInteractions ? "禁用" : "启用"}图像交互"),
                leading: Switch(
                  value: enableImageInteractions,
                  onChanged: (bool v) {
                    setState(() {
                      enableImageInteractions = v;
                    });
                  },
                ),
              ),
              ElevatedButton(
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.lightBlue,
                  padding: const EdgeInsets.all(20),
                ),
                onPressed: () async {
                  setState(() {
                    detectedValue = cameraDetectedValue = "";
                  });
                  final pickedFile = await ImagePicker()
                      .pickImage(source: ImageSource.gallery);
                  if (pickedFile != null) {
                    Navigator.of(context).push(MaterialPageRoute(
                        builder: (context) => SelectImageAreaTextDetect(
                              showLangScriptDropDown: true,
                              detectOnce: isDetectOnce,
                              enableImageInteractions: enableImageInteractions,
                              imagePath: pickedFile.path,
                              onDetectText: (v) {
                                setState(() {
                                  if (v is String) {
                                    detectedValue = v;
                                  } else if (v is List) {
                                    int counter = 0;
                                    for (var element in v) {
                                      detectedValue +=
                                          "$counter. \t\t $element \n\n";
                                      counter++;
                                    }
                                  }
                                });
                              },
                              onDetectError: (error) {
                                print(error);

                                // 这个错误仅在Android上发生,当用户尝试在最大缩放级别裁剪图像时,ML Kit会抛出最大32高度/宽度异常
                                if (error is PlatformException &&
                                    (error.message?.contains(
                                            "InputImage width and height should be at least 32!") ??
                                        false)) {
                                  ScaffoldMessenger.of(context)
                                      .showSnackBar(const SnackBar(
                                          content: Text(
                                              "选择的区域应能够裁剪出至少32宽度和高度的图像。")));
                                }
                              },
                            )));
                  }
                },
                child: const Text(
                  "从图库选择图片并检测文本",
                  style: TextStyle(
                      color: Colors.white,
                      fontSize: 16,
                      fontWeight: FontWeight.bold),
                ),
              ),
              ElevatedButton(
                style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.lightBlue,
                  padding: const EdgeInsets.all(20),
                ),
                onPressed: () async {
                  setState(() {
                    detectedValue = cameraDetectedValue = "";
                  });
                  var values = await Navigator.of(context).push(
                      MaterialPageRoute(
                          builder: (context) => Stack(
                                children: [
                                  LiveTextRecognizerView(
                                    initialRecognitionScript:
                                        initialRecognitionScript,
                                    showLangScriptDropDown: true,
                                  ),
                                ],
                              )));

                  setState(() {
                    if (values is List) {
                      int counter = 0;
                      for (var element in values) {
                        cameraDetectedValue +=
                            "$counter. \t\t ${(element as DetectedTextInfo).text} \n\n";
                        counter++;
                      }
                    }
                    print("cameraDetectedValue $cameraDetectedValue");
                  });
                },
                child: const Text(
                  "实时摄像头文本检测",
                  style: TextStyle(
                      color: Colors.white,
                      fontSize: 16,
                      fontWeight: FontWeight.bold),
                ),
              ),
              const SizedBox(height: 20),
              Text(
                  '${isDetectOnce || cameraDetectedValue.isEmpty ? "单次" : "多次"}检测结果:',
                  style: Theme.of(context).textTheme.titleLarge),
              const SizedBox(height: 20),
              Flexible(
                child: SingleChildScrollView(
                  child: Text(
                    detectedValue.isEmpty && cameraDetectedValue.isEmpty
                        ? "请选择图片并检测文本,或从实时摄像头检测并选择/复制检测到的文本"
                        : cameraDetectedValue.isNotEmpty
                            ? cameraDetectedValue
                            : detectedValue,
                    style: Theme.of(context).textTheme.bodyMedium,
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter文本区域检测插件flutter_text_detect_area的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文本区域检测插件flutter_text_detect_area的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成和使用flutter_text_detect_area插件的一个基本示例。请注意,这个插件的具体实现和功能可能有所不同,因为插件会随着时间的推移进行更新和变化。以下代码是基于假设该插件存在并具有基本文本区域检测功能。

首先,确保你已经在pubspec.yaml文件中添加了flutter_text_detect_area依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_text_detect_area: ^x.y.z  # 替换为实际版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以使用以下代码来集成和使用这个插件:

import 'package:flutter/material.dart';
import 'package:flutter_text_detect_area/flutter_text_detect_area.dart';  // 假设插件提供了这个导入路径

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Text Area Detection Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: TextAreaDetectionScreen(),
    );
  }
}

class TextAreaDetectionScreen extends StatefulWidget {
  @override
  _TextAreaDetectionScreenState createState() => _TextAreaDetectionScreenState();
}

class _TextAreaDetectionScreenState extends State<TextAreaDetectionScreen> {
  final TextEditingController _controller = TextEditingController();
  List<TextDetectionResult> _results = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Text Area Detection'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TextField(
              controller: _controller,
              decoration: InputDecoration(
                labelText: 'Enter text here...',
                border: OutlineInputBorder(),
              ),
              maxLines: 10,  // 允许多行输入
              onChanged: (value) {
                // 每当文本变化时调用文本检测函数
                detectTextArea(value);
              },
            ),
            SizedBox(height: 20),
            Expanded(
              child: ListView.builder(
                itemCount: _results.length,
                itemBuilder: (context, index) {
                  final result = _results[index];
                  return Padding(
                    padding: const EdgeInsets.symmetric(vertical: 8.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text('Detected Text: ${result.text}'),
                        Text('Position: ${result.rect}'),  // 假设rect是一个表示位置的Rect对象
                      ],
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  // 这是一个假设的函数,用于演示文本检测的逻辑
  // 实际插件可能有不同的API和方法来调用文本检测
  void detectTextArea(String text) {
    setState(() {
      _results = flutterTextDetectArea(text);  // 假设这是插件提供的方法
    });
  }

  // 这是一个假设的方法,它返回TextDetectionResult的列表
  // 实际插件可能有不同的返回类型和方法签名
  List<TextDetectionResult> flutterTextDetectArea(String text) {
    // 这里应该调用插件的实际检测逻辑
    // 由于插件的具体实现未知,这里仅返回模拟数据
    return [
      TextDetectionResult('Hello', Rect.fromLTWH(10, 10, 50, 20)),
      TextDetectionResult('World', Rect.fromLTWH(70, 10, 50, 20)),
    ];
  }
}

// 这是一个假设的TextDetectionResult类,用于存储检测结果
class TextDetectionResult {
  final String text;
  final Rect rect;

  TextDetectionResult(this.text, this.rect);
}

请注意,上面的代码是一个假设的示例,因为flutter_text_detect_area插件的实际API和类可能与此不同。你需要查阅该插件的官方文档或源代码来了解其实际的API和使用方法。

此外,由于插件可能并不实际存在或具有上述功能,因此上述代码主要是为了演示如何在Flutter中集成和使用一个假设的文本区域检测插件。如果你确实有这样的需求,建议寻找或开发一个合适的插件来满足你的具体需求。

回到顶部