Flutter光学字符识别插件ocr_data_extractor的使用

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

Flutter光学字符识别插件ocr_data_extractor的使用

本README描述了该包。如果您将此包发布到pub.dev,则此README的内容将出现在您的包的首页上。

有关编写良好的包README的指南,请参阅编写包页面

有关开发包的一般信息,请参阅Dart指南的创建包和Flutter指南的开发包和插件

功能

使用此插件可以从图像中提取文本并处理以返回所需的数据。只需将图像路径传递给选定的函数即可。

开始使用

在您的podfile中添加以下代码:

platform :ios, '10.0'

使用方法

以下代码从图像中提取所有具有6个或更多数字的数字,并删除时间和日期。

List<String> numbers = await OCRController().getNumberList(pickedFile!.path);

以下代码从图像中提取航班列表中的所有名字并提取其详细信息。它接受一个列表作为参数。

dynamic passengers = await OCRController().getNamesList(pickedFile.path, names, 0);

完整示例代码

import 'package:camera_kit_ext/CameraKitExtController.dart';
import 'package:camera_kit_ext/CameraKitExtView.dart';
import 'package:example/consts.dart';
import 'package:example/line_drawing.dart';
import 'package:example/live_scan.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:ocr_data_extractor/classes.dart';
import 'package:ocr_data_extractor/ocr_data_extractor.dart';
import 'classes.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyTestPage(title: 'Back Up'),
    );
  }
}

class MyTestPage extends StatefulWidget {
  const MyTestPage({Key? key, required this.title}) : super(key: key);
  final String title;

  [@override](/user/override)
  State<MyTestPage> createState() => _MyTestPageState();
}

class _MyTestPageState extends State<MyTestPage> {
  final ImagePicker _picker = ImagePicker();
  bool loading = false;
  int selected = 0;
  int type = 0;
  List<String> results = ['', '', '', '', '', ''];
  List<Line> beforeLines = [];
  List<Line> afterLines = [];

  Future<void> _getPassengers() async {
    setState(() => loading = true);
    final pickedFile = await _picker.getImage(source: ImageSource.gallery, imageQuality: 50);
    List<Map<String, dynamic>> passengers = await OCRController().getPassengerList(pickedFile!.path, StaticLists.names);
    List<BackUpOCRPassenger> data = passengers.map((e) => BackUpOCRPassenger.fromJson(e)).toList();
    results = [
      OCRController().googleText,
      OCRController().sortedResult,
      '', '', '',
      data.join("\n"),
    ];
    beforeLines = OCRController().beforeLines;
    afterLines = OCRController().afterLines;
    setState(() => loading = false);
  }

  Future<void> _takePicture() async {
    setState(() => loading = true);
    String? path = await Navigator.of(context)
        .push(MaterialPageRoute(builder: (context) => const _TakePicture()));
    if (path?.isNotEmpty ?? false) {
      List<Map<String, dynamic>> passengers = await OCRController().getPassengerList(path!, StaticLists.names2);
      List<BackUpOCRPassenger> data = passengers.map((e) => BackUpOCRPassenger.fromJson(e)).toList();
      results = [
        OCRController().googleText,
        OCRController().sortedResult,
        '', '', '',
        data.join("\n\n"),
      ];
    }
    beforeLines = OCRController().beforeLines;
    afterLines = OCRController().afterLines;
    setState(() => loading = false);
  }

  showLines(bool isRaw) {
    Object o = Object(lines: isRaw ? beforeLines : afterLines);
    List<Line> lines = Object.fromJson(o.toJson()).lines ?? [];
    if (lines.isEmpty) {
      Get.snackbar('\nNothing to show!', "",
          duration: const Duration(seconds: 1),
          colorText: Colors.red,
          backgroundColor: Colors.white70);
      return;
    }
    Navigator.of(context).push(MaterialPageRoute(
        builder: (context) => LineDrawing(lines: [...lines])));
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    String showingText = '';
    if (selected == 0) {
      showingText = results.first;
    } else if (selected == 1) {
      showingText = results[type + 1];
    } else {
      showingText = results.last;
    }
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        actions: [
          IconButton(
            icon: const Icon(Icons.raw_on),
            onPressed: () => showLines(true),
          ),
          IconButton(
            icon: const Icon(Icons.raw_off),
            onPressed: () => showLines(false),
          ),
        ],
      ),
      body: loading
          ? const Center(child: CircularProgressIndicator(color: Colors.blue))
          : Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(children: [
                  Expanded(
                    child: InkWell(
                      child: Container(
                        padding: const EdgeInsets.all(12),
                        alignment: Alignment.center,
                        color: Colors.blue.withOpacity(0.5),
                        child: Text("Raw Data",
                            style: TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                                fontSize: 16,
                                decoration: 0 == selected
                                    ? TextDecoration.underline
                                    : TextDecoration.none)),
                      ),
                      onTap: () => setState(() => selected = 0),
                    ),
                  ),
                  const VerticalDivider(
                      color: Colors.white, width: 1, thickness: 1),
                  Expanded(
                    child: InkWell(
                      child: Container(
                        padding: const EdgeInsets.all(12),
                        alignment: Alignment.center,
                        color: Colors.blue.withOpacity(0.5),
                        child: Text(
                            type == 0
                                ? "Sorted"
                                : type == 1
                                    ? "X Axis"
                                    : type == 2
                                        ? "Y Axis"
                                        : "Slope",
                            style: TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                                fontSize: 16,
                                decoration: 1 == selected
                                    ? TextDecoration.underline
                                    : TextDecoration.none)),
                      ),
                      onTap: () => setState(() => selected = 1),
                    ),
                  ),
                  const VerticalDivider(
                      color: Colors.white, width: 1, thickness: 1),
                  Expanded(
                    child: InkWell(
                      child: Container(
                        padding: const EdgeInsets.all(12),
                        alignment: Alignment.center,
                        color: Colors.blue.withOpacity(0.5),
                        child: Text("Extracted",
                            style: TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                                fontSize: 16,
                                decoration: 2 == selected
                                    ? TextDecoration.underline
                                    : TextDecoration.none)),
                      ),
                      onTap: () => setState(() => selected = 2),
                    ),
                  ),
                ]),
                Expanded(
                  child: Container(
                    padding: const EdgeInsets.all(20),
                    child: SingleChildScrollView(child: Text(showingText)),
                  ),
                ),
              ],
            ),
      floatingActionButton: Row(
        children: [
          const SizedBox(width: 24),
          FloatingActionButton(
            heroTag: "btn 1",
            onPressed: () {
              Clipboard.setData(ClipboardData(text: showingText));
              Get.snackbar('\nCopied to Clipboard', "",
                  duration: const Duration(seconds: 1),
                  colorText: Colors.black,
                  backgroundColor: Colors.white70);
            },
            child: const Icon(Icons.copy),
          ),
          const Spacer(),
          FloatingActionButton(
            heroTag: "btn 2",
            onPressed: () {
              Navigator.of(context).push(
                  MaterialPageRoute(builder: (context) => const LiveScan()));
            },
            child: const Icon(Icons.video_camera_front),
          ),
          const SizedBox(width: 9),
          FloatingActionButton(
            heroTag: "btn 2.5",
            onPressed: _takePicture,
            child: const Icon(Icons.camera_alt),
          ),
          const SizedBox(width: 9),
          FloatingActionButton(
            heroTag: "btn 3",
            onPressed: _getPassengers,
            child: const Icon(Icons.attach_file),
          ),
        ],
      ),
    );
  }
}

class _TakePicture extends StatefulWidget {
  const _TakePicture({Key? key}) : super(key: key);

  [@override](/user/override)
  State<_TakePicture> createState() => _TakePictureState();
}

class _TakePictureState extends State<_TakePicture> {
  final CameraKitExtController _cameraKitExtController = CameraKitExtController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Scanner")),
      backgroundColor: Colors.white,
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: FloatingActionButton(
        onPressed: () => _cameraKitExtController
            .takePicture()
            .then((value) => Navigator.pop(context, value)),
        child: const Icon(Icons.camera_alt),
      ),
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        color: Colors.white,
        child: CameraKitExtView(
          cameraKitController: _cameraKitExtController,
          previewFlashMode: CameraFlashMode.auto,
          onPermissionDenied: () => Navigator.pop(context),
        ),
      ),
    );
  }
}

更多关于Flutter光学字符识别插件ocr_data_extractor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter光学字符识别插件ocr_data_extractor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用ocr_data_extractor插件进行光学字符识别(OCR)的代码示例。这个插件可以帮助你从图像中提取文本数据。

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

dependencies:
  flutter:
    sdk: flutter
  ocr_data_extractor: ^最新版本号 # 请替换为实际的最新版本号

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

接下来是一个完整的Flutter应用示例,展示如何使用ocr_data_extractor插件进行OCR操作:

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

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

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

class OcrScreen extends StatefulWidget {
  @override
  _OcrScreenState createState() => _OcrScreenState();
}

class _OcrScreenState extends State<OcrScreen> {
  String? ocrResult;
  final ImagePicker _picker = ImagePicker();
  final OcrDataExtractor _ocrDataExtractor = OcrDataExtractor();

  Future<void> _pickImage() async {
    final pickedFile = await _picker.pickImage(source: ImageSource.camera);

    if (pickedFile != null) {
      final filePath = pickedFile.path;
      _extractTextFromImage(filePath);
    }
  }

  Future<void> _extractTextFromImage(String filePath) async {
    try {
      final result = await _ocrDataExtractor.extractTextFromImage(filePath);
      setState(() {
        ocrResult = result;
      });
    } catch (e) {
      print("Error during OCR: $e");
      setState(() {
        ocrResult = "Error during OCR process.";
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OCR Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(
              'Extracted Text:',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 8),
            Text(
              ocrResult ?? 'No text extracted yet.',
              style: TextStyle(fontSize: 16),
              maxLines: 10,
              overflow: TextOverflow.ellipsis,
            ),
            SizedBox(height: 24),
            ElevatedButton(
              onPressed: _pickImage,
              child: Text('Pick Image and Extract Text'),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项:

  1. 权限处理:在Android上,你可能需要在AndroidManifest.xml中请求相机和存储权限。在iOS上,你需要在Info.plist中添加相应的权限描述。

  2. 错误处理:上面的示例中简单地捕获并打印了错误,但在实际应用中,你可能需要更优雅地处理错误,比如向用户显示错误信息。

  3. 依赖项:这个示例还使用了image_picker插件来选择图像。你需要在pubspec.yaml中添加这个依赖项,并运行flutter pub get来安装它。

dependencies:
  image_picker: ^最新版本号 # 请替换为实际的最新版本号

通过这些步骤,你应该能够在Flutter应用中成功实现OCR功能。

回到顶部