Flutter关键信息提取插件ktp_extractor的使用
Flutter关键信息提取插件ktp_extractor的使用
特性
- 自动KTP检测和裁剪:在图像中检测KTP区域并进行裁剪以供处理。
- 文本识别:使用OCR从KTP图像中提取文本。
- 数据解析:解析识别出的文本以提取特定字段,如身份证号(NIK)、姓名、出生日期、地址等。
- 易于集成:简单API,可轻松集成到您的Flutter应用程序中。
要求
iOS
- 最低iOS部署目标:15.5.0
- Xcode 15.3.0或更新版本
- Swift 5
- ML Kit不支持32位架构(i386和armv7)。ML Kit支持64位架构(x86_64和arm64)。您可以查看此列表来确认您的设备是否具有所需的能力。更多信息这里。
由于ML Kit不支持32位架构(i386和armv7),您需要在Xcode中排除armv7架构,以便运行flutter build ios
或flutter build ipa
。更多信息这里。
转到项目 > Runner > 构建设置 > 排除架构 > 任何SDK > armv7:
您的Podfile应如下所示:
platform :ios, '15.5.0' # 或更新版本
...
# 添加这一行:
$iOSVersion = '15.5.0' # 或更新版本
post_install do |installer|
# 添加这些行:
installer.pods_project.build_configurations.each do |config|
config.build_settings["EXCLUDED_ARCHS[sdk=*]"] = "armv7"
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $iOSVersion
end
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
# 添加这些行:
target.build_configurations.each do |config|
if Gem::Version.new($iOSVersion) > Gem::Version.new(config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'])
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $iOSVersion
end
end
end
end
请注意,最低IPHONEOS_DEPLOYMENT_TARGET
为15.5.0,您可以将其设置为更新版本但不能更旧。
Android
- minSdkVersion: 21
- targetSdkVersion: 33
- compileSdkVersion: 34
使用
从KTP图像中提取信息
import 'dart:io';
import 'package:ktp_extractor/ktp_extractor.dart';
void main() async {
// 加载您的图像文件(确保它包含KTP)
File imageFile = File('path_to_your_image.jpg');
// 裁剪图像以获取KTP区域(可选但推荐)
File? croppedImage = await KtpExtractor.cropImageForKtp(imageFile);
// 如果可用,使用裁剪后的图像进行处理
File imageToProcess = croppedImage ?? imageFile;
// 提取KTP信息
KtpModel ktpData = await KtpExtractor.extractKtp(imageToProcess);
// 访问提取的数据
print('NIK: ${ktpData.nik}');
print('Name: ${ktpData.name}');
print('Birth Date: ${ktpData.birthDay}');
print('Address: ${ktpData.address}');
// ... 访问其他字段
}
示例代码
以下是一个完整的示例演示如何使用ktp_extractor
插件:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:ktp_extractor/ktp_extractor.dart';
import 'package:ktp_extractor/utils/utils.dart';
void main() {
runApp(const MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ImagePicker? _imagePicker;
File? _image;
KtpModel? _ktpModel;
[@override](/user/override)
void initState() {
super.initState();
_imagePicker = ImagePicker();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('插件示例应用'),
),
body: ListView(
children: [
if (_image != null) ...[
Image.file(_image!),
const SizedBox(
height: 12,
),
],
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: ElevatedButton(
onPressed: _getImageAsset,
child: const Text('从资源中选择'),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: ElevatedButton(
child: const Text('从相册中选择'),
onPressed: () => _getImage(ImageSource.gallery),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: ElevatedButton(
child: const Text('拍照'),
onPressed: () => _getImage(ImageSource.camera),
),
),
if (_ktpModel != null)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'省 : ${_ktpModel!.province}',
maxLines: null,
),
Text(
'市/县 : ${_ktpModel!.city}',
maxLines: null,
),
Text(
'身份证号 : ${_ktpModel!.nik}',
maxLines: null,
),
Text(
'姓名 : ${_ktpModel!.name}',
maxLines: null,
),
Text(
'出生地 : ${_ktpModel!.placeBirth}',
maxLines: null,
),
Text(
'出生日期 : ${_ktpModel!.birthDay}',
maxLines: null,
),
Text(
'住址 : ${_ktpModel!.address}',
maxLines: null,
),
Text(
'\t\t\t门牌号 : ${_ktpModel!.rt} / ${_ktpModel!.rw}',
maxLines: null,
),
Text(
'\t\t\t社区 : ${_ktpModel!.subDistrict}',
maxLines: null,
),
Text(
'\t\t\t区 : ${_ktpModel!.district}',
maxLines: null,
),
Text(
'宗教 : ${_ktpModel!.religion}',
maxLines: null,
),
Text(
'婚姻状况 : ${_ktpModel!.marital}',
maxLines: null,
),
Text(
'职业 : ${_ktpModel!.occupation}',
maxLines: null,
),
Text(
'国籍 : ${_ktpModel!.nationality}',
maxLines: null,
),
Text(
'有效期至 : ${_ktpModel!.validUntil}',
maxLines: null,
),
],
),
),
],
),
);
}
Future _getImage(ImageSource source) async {
setState(() {
_image = null;
_ktpModel = null;
});
final pickedFile = await _imagePicker?.pickImage(source: source);
if (pickedFile != null) {
_processFile(pickedFile.path);
}
}
Future _getImageAsset() async {
setState(() {
_image = null;
_ktpModel = null;
});
final manifestContent = await rootBundle.loadString('AssetManifest.json');
final Map<String, dynamic> manifestMap = json.decode(manifestContent);
final assets = manifestMap.keys
.where((String key) => key.contains('images/'))
.where((String key) =>
key.contains('.jpg') ||
key.contains('.jpeg') ||
key.contains('.png') ||
key.contains('.webp'))
.toList();
showDialog(
// 忽略:使用build_context_synchronously
context: context,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'选择图像',
style: TextStyle(fontSize: 20),
),
ConstrainedBox(
constraints:
BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.7),
child: SingleChildScrollView(
child: Column(
children: [
for (final path in assets)
GestureDetector(
onTap: () async {
Navigator.of(context).pop();
_processFile(await getAssetPath(path));
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(path),
),
),
],
),
),
),
ElevatedButton(
onPressed: () => Navigator.of(context).pop(), child: const Text('取消')),
],
),
),
);
});
}
Future _processFile(String path) async {
_image = await KtpExtractor.cropImageForKtp(File(path));
_image ??= File(path);
_ktpModel = await KtpExtractor.extractKtp(_image!);
setState(() {});
// _path = path;
// final inputImage = InputImage.fromFilePath(path);
// widget.onImage(inputImage);
}
}
更多关于Flutter关键信息提取插件ktp_extractor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复