Flutter文档检测插件document_detector的使用
Flutter文档检测插件document_detector的使用
插件用于调用Android和iOS的原生SDK。如果您有任何疑问,请发送电子邮件至我们的移动负责人邮箱:daniel.seitenfus@combateafraude.com。
目前支持的文件包括身份证(RG)、驾驶证(CNH)、外国人身份证(RNE)、车辆登记证(CRLV)、工作证(CTPS)和护照。如果您有其他文件建议,请联系我们!
隐私政策和使用条款
使用我们的插件时,请确保您已同意我们的隐私政策和使用条款。
前提条件
最低配置要求
配置 | 版本 |
---|---|
Flutter | 1.12+ |
Dart | 2.12+ |
Android API | 21+ |
Compile SDK Version | 30+ |
iOS | 11.0+ |
如果您的Dart版本低于2.12,请检查此兼容版本。
设置
Android
在ROOT_PROJECT/android/app/build.gradle
文件中添加以下内容:
android {
...
dataBinding.enabled = true
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
aaptOptions {
noCompress "tflite"
}
}
iOS
在ROOT_PROJECT/ios/Podfile
文件末尾添加以下内容:
source 'https://github.com/combateafraude/iOS.git'
source 'https://cdn.cocoapods.org/' # 或者 'https://github.com/CocoaPods/Specs' 如果CDN不可用
最后,在ROOT_PROJECT/ios/Runner/Info.plist
文件中添加权限:
<key>NSCameraUsageDescription</key>
<string>为了读取文档</string>
<!-- 仅在文档上传流程中需要 -->
<key>NSPhotoLibraryUsageDescription</key>
<string>为了选择图像</string>
为了启用葡萄牙语的文字和语音功能,在项目目录ROOT_PROJECT/ios
中,打开.xcworkspace
文件,并在Xcode中通过Project > Info > Localizations
添加葡萄牙语(巴西)。
Flutter
在ROOT_PROJECT/pubspec.yaml
文件中添加插件:
dependencies:
document_detector:
git:
url: https://github.com/combateafraude/Flutter.git
ref: document-detector-v5.23.0
禁用安全验证以进行测试
我们不断采取措施使产品更加安全,减少身份欺诈的可能性。SDK包含一些可能会阻止在某些上下文中运行的限制。为了禁用它们,您可以使用如下示例中的方法:
DocumentDetectorAndroidSettings androidSettings =
DocumentDetectorAndroidSettings(
emulatorSettings: true,
rootSettings: true,
useDeveloperMode: true,
useAdb: true,
useDebug: true,
);
documentDetector.setAndroidSettings(androidSettings);
注意! 仅在测试环境中建议禁用安全验证。对于生产环境的应用发布,请使用默认设置。
使用示例
DocumentDetector documentDetector = new DocumentDetector(mobileToken: mobileToken);
documentDetector.setDocumentFlow(List<DocumentDetectorStep> documentSteps);
// 其他自定义参数
DocumentDetectorResult documentDetectorResult = await documentDetector.start();
if (documentDetectorResult is DocumentDetectorSuccess) {
// SDK成功结束并捕获了文档照片
} else if (documentDetectorResult is DocumentDetectorFailure) {
// SDK因某种失败而结束,文档照片未被捕捉
} else {
// 用户只是简单地关闭了SDK,没有任何结果
}
通用自定义设置
.documentDetector.setPeopleId(String peopleId)
.documentDetector.setAnalyticsSettings(bool useAnalytics)
.documentDetector.setDocumentFlow(List<DocumentDetectorStep> documentSteps)
.documentDetector.setPopupSettings(bool show)
.documentDetector.enableSound(bool enable)
.documentDetector.setNetworkSettings(int requestTimeout)
.documentDetector.setShowPreview(ShowPreview showPreview)
.documentDetector.setAutoDetection(bool enable)
.documentDetector.setCurrentStepDoneDelay(bool showDelay, int delay)
.documentDetector.setMessageSettings(MessageSettings messageSettings)
.documentDetector.setGetImageUrlExpireTime(String expireTime)
.documentDetector.setAndroidSettings(DocumentDetectorAndroidSettings androidSettings)
.documentDetector.setIosSettings(DocumentDetectorIosSettings iosSettings)
.documentDetector.setUploadSettings(UploadSettings uploadSettings)
示例
ShowPreview showPreview = new ShowPreview(
show: true,
title: "照片看起来如何?",
subtitle: "看看照片是否清晰",
confirmLabel: "是的,看起来很好!",
retryLabel: "重新拍摄");
documentDetector.setShowPreview(showPreview);
MessageSettings messageSettings = new MessageSettings(
fitTheDocumentMessageResIdName: "示例消息",
holdItMessageResIdName:"示例消息",
verifyingQualityMessageResIdName: "示例消息"
lowQualityDocumentMessageResIdName:"示例消息" ,
uploadingImageMessageResIdName:"示例消息",
openDocumentWrongMessage: "示例消息",
showOpenDocumentMessage: true);
documentDetector.setMessageSettings(messageSettings);
Android 自定义设置
DocumentDetectorStepCustomizationAndroid customizationAndroid = new DocumentDetectorStepCustomizationAndroid(
stepLabelStringResName: "my_custom_string",
illustrationDrawableResName: "my_custom_illustration",
audioRawResName: "my_custom_audio"
);
DocumentDetectorAndroidSettings androidSettings = new DocumentDetectorAndroidSettings(
enableSwitchCameraButton: false,
compressQuality: 50,
resolution: Resolution.QUAD_HD
);
iOS 自定义设置
DocumentDetectorIosSettings iosSettings = new DocumentDetectorIosSettings(
enableManualCapture: true,
timeEnableManualCapture: 15000,
compressQuality: 1,
resolution: IosResolution.HD1280x720
);
收集结果
DocumentDetector
的结果对象是一个抽象类型DocumentDetectorResult
。它可能是DocumentDetectorSuccess
、DocumentDetectorFailure
或DocumentDetectorClosed
的一个实例。
DocumentDetectorSuccess
字段 | 备注 |
---|---|
List<Capture> captures |
文档捕获列表 |
String type |
SDK检测到的文档类型 |
String trackingId |
在服务器上的执行标识符 |
Capture
字段 | 备注 |
---|---|
String imagePath |
图像在设备上的完整路径 |
String imageUrl |
图像存储在临时服务器上的URL |
String label |
捕获的检测标签 |
double quality |
图像的质量,范围为1.0到5.0 |
DocumentDetectorFailure
字段 | 备注 |
---|---|
String message |
友好的错误信息 |
String type |
结束SDK的错误类型 |
iOS视图定制
要定制iOS视图,需要将Flutter插件本地添加到项目中。使用ViewCode原生方法实现定制。
点击这里查看一个示例,其中包含该功能的使用指南。
示例代码
import 'package:document_detector/android/android_settings.dart';
import 'package:document_detector/android/capture_stage/capture_mode.dart';
import 'package:document_detector/android/capture_stage/capture_stage.dart';
import 'package:document_detector/android/customization.dart';
import 'package:document_detector/android/maskType.dart';
import 'package:document_detector/android/resolution.dart';
import 'package:document_detector/ios/ios_resolution.dart';
import 'package:document_detector/message_settings.dart';
import 'package:document_detector/show_preview.dart';
import 'package:document_detector/document_detector_step.dart';
import 'package:document_detector/document_type.dart';
import 'package:document_detector/ios/ios_settings.dart';
import 'package:document_detector/result/capture.dart';
import 'package:document_detector/result/document_detector_failure.dart';
import 'package:document_detector/result/document_detector_result.dart';
import 'package:document_detector/result/document_detector_success.dart';
import 'package:document_detector/upload_settings.dart';
import 'package:flutter/material.dart';
import 'package:document_detector/document_detector.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _result = "";
String _description = "";
String mobileToken = "";
[@override](/user/override)
void initState() {
super.initState();
requestPermissions();
}
void requestPermissions() async {
await [
Permission.camera,
].request();
}
void startDocumentDetector(List<DocumentDetectorStep> documentSteps) async {
String result = "";
String description = "";
DocumentDetector documentDetector =
new DocumentDetector(mobileToken: mobileToken);
DocumentDetectorIosSettings documentDetectorIosSettings =
new DocumentDetectorIosSettings(
enableManualCapture: true, timeEnableManualCapture: 15000);
DocumentDetectorAndroidSettings detectorAndroidSettings =
new DocumentDetectorAndroidSettings(
enableSwitchCameraButton: false,
compressQuality: 50,
resolution: Resolution.QUAD_HD);
DocumentDetectorCustomizationAndroid documentDetectorCustomizationAndroid =
new DocumentDetectorCustomizationAndroid(maskType: MaskType.DETAILED);
MessageSettings messageSettings = new MessageSettings(
openDocumentWrongMessage: "关闭文档",
showOpenDocumentMessage: true,
unsupportedDocumentMessage: "对不起,此文档不受支持");
DocumentDetectorIosSettings iosSettings = new DocumentDetectorIosSettings(
resolution: IosResolution.HD1280x720, compressQuality: 1);
List<String> formats = ["PDF", "PNG"];
documentDetector.setIosSettings(iosSettings);
documentDetector.setMessageSettings(messageSettings);
documentDetector.setDocumentFlow(documentSteps);
documentDetector.setAndroidSettings(detectorAndroidSettings);
// 将其他参数放在这里
try {
DocumentDetectorResult documentDetectorResult =
await documentDetector.start();
if (documentDetectorResult is DocumentDetectorSuccess) {
result = "成功!";
description = "类型: " +
(documentDetectorResult.type != null
? documentDetectorResult.type
: "null");
for (Capture capture in documentDetectorResult.captures) {
description += "\n\n\t捕获:\n\timagePath: " +
capture.imagePath +
"\n\timageUrl: " +
(capture.imageUrl != null
? capture.imageUrl.split("?")[0] + "..."
: "null") +
"\n\tlabel: " +
(capture.label != null ? capture.label : "null") +
"\n\t质量: " +
(capture.quality != null ? capture.quality.toString() : "null");
}
} else if (documentDetectorResult is DocumentDetectorFailure) {
result = "失败!";
description = "\t类型: " +
documentDetectorResult.type +
"\n\t消息: " +
documentDetectorResult.message;
} else {
result = "已关闭!";
}
} on PlatformException catch (err) {
result = "异常!";
description = err.message;
}
if (!mounted) return;
setState(() {
_result = result;
_description = description;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('DocumentDetector插件示例'),
),
body: Container(
margin: const EdgeInsets.all(20.0),
child: Column(
children: [
Row(
children: [
ElevatedButton(
child: Text('启动CNH文档检测器'),
onPressed: () async {
startDocumentDetector([
new DocumentDetectorStep(
document: DocumentType.CNH_FRONT),
new DocumentDetectorStep(
document: DocumentType.CNH_BACK)
]);
},
)
],
),
Row(
children: [
ElevatedButton(
child: Text('启动RG文档检测器'),
onPressed: () async {
startDocumentDetector([
new DocumentDetectorStep(
document: DocumentType.RG_FRONT),
new DocumentDetectorStep(
document: DocumentType.RG_BACK)
]);
},
)
],
),
Row(
children: [
ElevatedButton(
child: Text('启动RNE文档检测器'),
onPressed: () async {
startDocumentDetector([
new DocumentDetectorStep(
document: DocumentType.RNE_FRONT),
new DocumentDetectorStep(
document: DocumentType.RNE_BACK)
]);
},
)
],
),
Row(
children: [
Container(
margin: EdgeInsets.only(top: 10.0),
child: Text("结果: $_result"))
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text("描述:\n$_description",
overflow: TextOverflow.clip),
)
],
),
],
))));
}
}
更多关于Flutter文档检测插件document_detector的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter文档检测插件document_detector的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
document_detector
是一个用于在 Flutter 应用程序中检测文档的插件。它可以帮助你从图像中检测并提取文档的边缘。这个插件通常用于扫描文档、自动裁剪图像边缘等场景。
安装插件
首先,你需要在 pubspec.yaml
文件中添加 document_detector
插件的依赖:
dependencies:
flutter:
sdk: flutter
document_detector: ^1.0.0 # 请检查最新版本
然后运行 flutter pub get
来安装插件。
使用插件
1. 导入插件
在你的 Dart 文件中导入 document_detector
插件:
import 'package:document_detector/document_detector.dart';
2. 初始化插件
在使用插件之前,通常需要先初始化它:
DocumentDetector documentDetector = DocumentDetector();
3. 检测文档边缘
你可以使用 detectDocument
方法来检测图像中的文档边缘。这个方法通常需要传入一个图像文件的路径或图像数据。
String imagePath = 'path_to_your_image.jpg';
try {
List<Offset> documentCorners = await documentDetector.detectDocument(imagePath);
// documentCorners 是一个包含四个 Offset 的列表,表示检测到的文档的四个角
if (documentCorners != null && documentCorners.length == 4) {
print('Document detected with corners: $documentCorners');
} else {
print('No document detected.');
}
} catch (e) {
print('Error detecting document: $e');
}
4. 处理检测结果
detectDocument
方法返回一个包含四个 Offset
的列表,这些 Offset
表示检测到的文档的四个角的坐标。你可以使用这些坐标来裁剪图像、绘制文档边界等。
5. 绘制文档边界(可选)
如果你想在 Flutter 中绘制检测到的文档边界,可以使用 CustomPaint
和 Canvas
:
class DocumentPainter extends CustomPainter {
final List<Offset> corners;
DocumentPainter(this.corners);
@override
void paint(Canvas canvas, Size size) {
if (corners.length == 4) {
final paint = Paint()
..color = Colors.red
..strokeWidth = 2.0
..style = PaintingStyle.stroke;
final path = Path()
..moveTo(corners[0].dx, corners[0].dy)
..lineTo(corners[1].dx, corners[1].dy)
..lineTo(corners[2].dx, corners[2].dy)
..lineTo(corners[3].dx, corners[3].dy)
..close();
canvas.drawPath(path, paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
然后在你的 Widget
中使用这个 CustomPainter
:
CustomPaint(
painter: DocumentPainter(documentCorners),
child: Image.file(File(imagePath)),
)