Flutter文档阅读插件flutter_document_reader_api_beta的使用

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

Flutter文档阅读插件 flutter_document_reader_api_beta 的使用

Regula Document Reader SDK 允许您读取各种类型的识别文档,如护照、驾照、身份证等。所有处理都在设备上完全离线进行,不会有任何数据离开您的设备。您可以使用原生相机扫描文档或从相册中选择图片来提取其中的所有数据。

文档

您可以在 这里 查看完整的文档。

许可证

要获取生产许可证或其他购买信息,请提交一个咨询请求,我们的销售团队会尽快与您联系。

支持

如果您需要任何帮助或想报告错误/提出改进建议,请不要犹豫,联系我们


示例 Demo

下面是一个完整的示例代码,展示了如何使用 flutter_document_reader_api_beta 插件来读取和显示文档信息。

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/services.dart';
import 'package:flutter_document_reader_api_beta/flutter_document_reader_api.dart';

void main() => runApp(MyApp());

class MyAppState extends State<MyApp> {
  var documentReader = DocumentReader.instance;

  var status = "Loading...";
  var portrait = Image.asset('assets/images/portrait.png');
  var docImage = Image.asset('assets/images/id.png');
  var selectedScenario = Scenario.MRZ;
  List<DocReaderScenario> scenarios = [];
  Object setStatus(String s) => {setState(() => status = s)};

  var doRfid = false;
  var isReadingRfid = false;
  var rfidCustomUiExample = RFIDCustomUI.empty();
  var rfidOption = RfidOption.Basic;

  var colorPrimary = Colors.blue;

  void init() async {
    super.initState();
    if (!await initializeReader()) return;
    setStatus("Ready");
    setState(() => scenarios = documentReader.availableScenarios);
  }

  void handleCompletion(DocReaderAction action, Results? results, DocReaderException? error) {
    if (error != null) print(error.message);
    if (action.stopped() && !shouldRfid(results)) {
      displayResults(results);
    } else if (action.finished() && shouldRfid(results)) {
      readRfid();
    }
  }

  void displayResults(Results? results) async {
    isReadingRfid = false;
    clearResults();
    if (results == null) return;

    var name = await results.textFieldValueByType(FieldType.SURNAME_AND_GIVEN_NAMES);
    var newDocImage = await results.graphicFieldImageByType(GraphicFieldType.DOCUMENT_IMAGE);
    var newPortrait = await results.graphicFieldImageByType(GraphicFieldType.PORTRAIT);

    setState(() {
      status = name ?? "Ready";
      if (newDocImage != null) docImage = Image.memory(newDocImage);
      if (newPortrait != null) portrait = Image.memory(newPortrait);
    });
  }

  void clearResults() {
    setState(() {
      status = "Ready";
      docImage = Image.asset('assets/images/id.png');
      portrait = Image.asset('assets/images/portrait.png');
    });
  }

  void readRfid() {
    isReadingRfid = true;
    if (rfidOption == RfidOption.Basic) basicRfid();
    if (rfidOption == RfidOption.Advanced) advancedRfid();
    if (rfidOption == RfidOption.Custom) rfidCustomUiExample.run();
  }

  void basicRfid() {
    documentReader.rfid(RFIDConfig(handleCompletion));
  }

  void advancedRfid() {
    var config = RFIDConfig(handleCompletion);

    config.onChipDetected = () => print("Chip detected, reading rfid.");
    config.onRetryReadChip = (error) async {
      var message = await error.code.getTranslation();
      print("Reading interrupted: $message. Retrying...");
    };

    documentReader.rfid(config);
  }

  bool shouldRfid(Results? results) =>
      doRfid && !isReadingRfid && results != null && results.chipPage != 0;

  Widget ui() {
    return Column(
      children: [
        documentImages(),
        scenarioSelector(),
        rfidCheckbox(),
        scanButtons()
      ],
    );
  }

  Widget documentImages() {
    return Container(
      padding: const EdgeInsets.only(top: 10, bottom: 10),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          image("Portrait", 150, 150, portrait.image),
          image("Document image", 150, 200, docImage.image),
        ],
      ),
    );
  }

  Widget scenarioSelector() {
    return Expanded(
      child: Container(
        color: const Color.fromARGB(5, 10, 10, 10),
        child: ListView.builder(
          itemCount: scenarios.length,
          itemBuilder: (_, int index) => radioButton(index),
        ),
      ),
    );
  }

  Widget rfidCheckbox() {
    var rfidCheckboxTitle = "Process rfid reading";
    if (!documentReader.isRFIDAvailableForUse) {
      rfidCheckboxTitle += " (unavailable)";
    }

    return CheckboxListTile(
      value: doRfid,
      title: Text(rfidCheckboxTitle),
      onChanged: (bool? value) {
        setState(() => doRfid = value! && documentReader.isRFIDAvailableForUse);
      },
    );
  }

  Widget scanButtons() {
    return Container(
      padding: const EdgeInsets.only(top: 10, bottom: 25),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          button("Scan document", () {
            clearResults();
            documentReader.scan(
              ScannerConfig.withScenario(selectedScenario),
              handleCompletion,
            );
          }),
          button("Scan image", () async {
            clearResults();
            documentReader.recognize(
              RecognizeConfig.withScenario(
                selectedScenario,
                RecognizeData.withImages(await getImages()),
              ),
              handleCompletion,
            );
          })
        ],
      ),
    );
  }

  Widget image(String title, double height, double width, ImageProvider image) {
    return Column(
      children: <Widget>[
        Text(title),
        Image(
          height: height,
          width: width,
          image: image,
        )
      ],
    );
  }

  Widget radioButton(int index) {
    Radio radio = Radio(
      value: scenarios[index].name,
      groupValue: selectedScenario.value,
      onChanged: (value) => setState(() {
        selectedScenario = Scenario.getByValue(value)!;
      }),
    );
    return Container(
      padding: const EdgeInsets.only(left: 40),
      child: ListTile(
        leading: radio,
        title: GestureDetector(
          onTap: () => radio.onChanged!(scenarios[index].name),
          child: Text(scenarios[index].caption),
        ),
      ),
    );
  }

  Widget button(String text, VoidCallback onPress) {
    return Container(
      width: 160,
      height: 40,
      padding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
      transform: Matrix4.translationValues(0, -7.5, 0),
      child: TextButton(
        style: ButtonStyle(
          foregroundColor: MaterialStateProperty.all<Color>(colorPrimary),
          backgroundColor: MaterialStateProperty.all<Color>(Colors.black12),
        ),
        onPressed: onPress,
        child: Text(text),
      ),
    );
  }

  Future<bool> initializeReader() async {
    setStatus("Initializing...");

    ByteData license = await rootBundle.load("assets/regula.license");
    var initConfig = InitConfig(license);
    initConfig.delayedNNLoad = true;
    var (success, error) = await documentReader.initializeReader(initConfig);

    if (!success) {
      setStatus(error!.message);
      printError(error);
    }
    rfidCustomUiExample = RFIDCustomUI(setState, setStatus, displayResults);
    return success;
  }

  void printError(DocReaderException error) =>
      print("Error: \n  code: ${error.code}\n  message: ${error.message}");

  Future<List<Uint8List>> getImages() async {
    setStatus("Processing image...");
    List<XFile> files = await ImagePicker().pickMultiImage();
    List<Uint8List> result = [];
    for (XFile file in files) {
      result.add(await file.readAsBytes());
    }
    return result;
  }

  [@override](/user/override)
  Widget build(_) {
    final ThemeData theme = ThemeData();
    return MaterialApp(
      theme: theme.copyWith(
        colorScheme: theme.colorScheme.copyWith(primary: colorPrimary, surfaceTint: colorPrimary),
      ),
      home: Scaffold(
        appBar: AppBar(title: Center(child: Text(status))),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            rfidCustomUiExample.build(),
            Visibility(
              visible: !rfidCustomUiExample.isShowing,
              child: Expanded(
                child: ui(),
              ),
            )
          ],
        ),
      ),
    );
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    init();
  }
}

enum RfidOption { Basic, Advanced, Custom }

class MyApp extends StatefulWidget {
  [@override](/user/override)
  MyAppState createState() => MyAppState();
}

更多关于Flutter文档阅读插件flutter_document_reader_api_beta的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文档阅读插件flutter_document_reader_api_beta的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成和使用flutter_document_reader_api_beta插件的示例代码。请注意,由于这是一个Beta版本的插件,API和功能可能会在未来发生变化。因此,请参考插件的官方文档以获取最新的使用指南。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加flutter_document_reader_api_beta依赖项:

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

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

2. 导入插件

在你的Dart文件中导入插件:

import 'package:flutter_document_reader_api_beta/flutter_document_reader_api_beta.dart';

3. 初始化插件并显示文档

下面是一个简单的示例,展示了如何初始化插件并显示一个PDF文档。

import 'package:flutter/material.dart';
import 'package:flutter_document_reader_api_beta/flutter_document_reader_api_beta.dart';

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

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

class DocumentReaderScreen extends StatefulWidget {
  @override
  _DocumentReaderScreenState createState() => _DocumentReaderScreenState();
}

class _DocumentReaderScreenState extends State<DocumentReaderScreen> {
  late DocumentReaderController _controller;

  @override
  void initState() {
    super.initState();
    _controller = DocumentReaderController();
    // 加载文档,这里假设你有一个PDF文件的URL
    _controller.loadFile(Uri.parse('https://example.com/path/to/your/document.pdf'));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Document Reader'),
      ),
      body: Center(
        child: DocumentReaderView(
          controller: _controller,
        ),
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

4. 处理更多功能

flutter_document_reader_api_beta插件可能提供了更多的功能,比如缩放、翻页、搜索等。你可以参考插件的官方文档来实现这些功能。

例如,如果你想添加缩放功能,你可以使用_controllerzoomIn()zoomOut()方法:

FloatingActionButton(
  onPressed: () {
    _controller.zoomIn();
  },
  tooltip: 'Zoom In',
  child: Icon(Icons.add),
),
FloatingActionButton(
  onPressed: () {
    _controller.zoomOut();
  },
  tooltip: 'Zoom Out',
  child: Icon(Icons.remove),
),

注意事项

  • 确保你的PDF文件URL是有效的,并且文件可以公开访问。
  • 插件可能还在开发中,所以请检查GitHub仓库或pub.dev页面上的最新信息和更新。
  • 如果遇到任何问题,请查阅插件的issue跟踪器或提交新的问题。

希望这个示例能帮助你开始使用flutter_document_reader_api_beta插件!

回到顶部