Flutter文档扫描插件flutter_twain_scanner的使用
Flutter文档扫描插件flutter_twain_scanner的使用
插件简介
flutter_twain_scanner
是一个Flutter插件,用于开发跨平台应用程序,可以从TWAIN (32-bit/64-bit)、WIA、SANE、ICA和eSCL扫描仪中数字化文档。该插件提供了可调用的方法,支持开源TWAIN(仅限64位)和Dynamsoft Service REST API。
Dynamsoft Service REST API
默认情况下,REST API的主机地址设置为 http://127.0.0.1:18622
。以下是API的主要方法:
方法 | 端点 | 描述 | 参数 | 响应 |
---|---|---|---|---|
GET | /DWTAPI/Scanners |
获取扫描仪列表 | 无 | 200 OK 包含扫描仪列表 |
POST | /DWTAPI/ScanJobs |
创建扫描任务 | license , device , config |
201 Created 包含任务ID |
GET | /DWTAPI/ScanJobs/:id/NextDocument |
获取文档图像 | id : 任务ID |
200 OK 包含图像流 |
DELETE | /DWTAPI/ScanJobs/:id |
删除扫描任务 | id : 任务ID |
200 OK |
安装Dynamsoft Service
要使Dynamsoft Service正常工作,请按照以下步骤操作:
-
安装Dynamsoft Service:
- Windows: 安装 Dynamsoft-Service-Setup.msi
- macOS: 安装 Dynamsoft-Service-Setup.pkg
- Linux:
-
申请免费试用许可证:
- 访问 Dynamsoft官网 申请免费试用许可证。
Dynamsoft Service配置
安装Dynamsoft Service后,可以通过浏览器访问 http://127.0.0.1:18625/
来配置主机和端口设置。默认主机IP地址为 127.0.0.1
。如果希望在办公室内从桌面、移动和Web应用程序访问服务,可以将主机设置更新为局域网IP地址,例如 192.168.8.72
。
API使用
Open Source TWAIN (Windows 64-bit only)
-
获取TWAIN兼容扫描仪列表:
List<String> scanners = await _flutterTwainScannerPlugin.getDataSources();
-
从选定扫描仪扫描文档:
int index = _scanners.indexOf(_selectedScanner!); List<String> documentPaths = await _flutterTwainScannerPlugin.scanDocument(index);
Dynamsoft Service (Windows, macOS, Linux, Android, iOS and Web)
-
获取TWAIN、WIA和eSCL兼容扫描仪列表:
final DynamsoftService dynamsoftService = DynamsoftService(); String host = 'http://127.0.0.1:18622'; final scanners = await dynamsoftService.getDevices(host, ScannerType.TWAINSCANNER | ScannerType.TWAINX64SCANNER);
-
删除扫描任务:
await dynamsoftService.deleteJob(host, jobId);
-
保存扫描任务中的图像到目录:
List<Uint8List> paths = await dynamsoftService.getImageFiles(host, jobId, './');
-
从扫描任务中获取图像流:
List<Uint8List> paths = await dynamsoftService.getImageStreams(host, jobId);
-
创建新的扫描任务:
final Map<String, dynamic> parameters = { 'license': 'LICENSE-KEY', 'device': devices[index]['device'], }; parameters['config'] = { 'IfShowUI': false, 'PixelType': 2, 'Resolution': 200, 'IfFeederEnabled': false, 'IfDuplexEnabled': false, }; final String jobId = await dynamsoftService.scanDocument(host, parameters);
完整示例Demo
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_twain_scanner/flutter_twain_scanner.dart';
import 'package:flutter_twain_scanner/dynamsoft_service.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _flutterTwainScannerPlugin = FlutterTwainScanner();
List<String> scannerNames = [];
String? _selectedScanner;
String host = 'http://192.168.8.72:18622'; // 替换为您的局域网IP地址
final DynamsoftService dynamsoftService = DynamsoftService();
List<dynamic> devices = [];
List<Uint8List> imagePaths = [];
[@override](/user/override)
void initState() {
super.initState();
initPlatformState();
}
// 平台消息是异步的,因此我们在异步方法中初始化
Future<void> initPlatformState() async {
if (!mounted) return;
}
Future<void> _scanDocument(int index) async {
final Map<String, dynamic> parameters = {
'license': 'LICENSE-KEY', // 替换为您的许可证密钥
'device': devices[index]['device'],
};
parameters['config'] = {
'IfShowUI': false,
'PixelType': 2, // 0: 黑白, 1: 灰度, 2: 彩色
'Resolution': 200, // 分辨率
'IfFeederEnabled': false, // 是否启用进纸器
'IfDuplexEnabled': false, // 是否启用双面扫描
};
try {
final String jobId = await dynamsoftService.scanDocument(host, parameters);
if (jobId != '') {
List<Uint8List> paths = await dynamsoftService.getImageStreams(host, jobId);
await dynamsoftService.deleteJob(host, jobId);
if (paths.isNotEmpty) {
setState(() {
imagePaths.insertAll(0, paths);
});
}
}
} catch (error) {
print('An error occurred: $error');
}
}
[@override](/user/override)
Widget build(BuildContext context) {
Row row = Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
MaterialButton(
textColor: Colors.white,
color: Colors.blue,
onPressed: () async {
try {
final scanners = await dynamsoftService.getDevices(host,
ScannerType.TWAINSCANNER | ScannerType.TWAINX64SCANNER);
for (var i = 0; i < scanners.length; i++) {
devices.add(scanners[i]);
scannerNames.add(scanners[i]['name']);
}
if (devices.isNotEmpty) {
setState(() {
_selectedScanner = devices[0]['name'];
});
}
} catch (error) {
print('An error occurred: $error');
}
},
child: const Text('List Scanners'),
),
MaterialButton(
textColor: Colors.white,
color: Colors.blue,
onPressed: () async {
if (_selectedScanner != null) {
int index = scannerNames.indexOf(_selectedScanner!);
await _scanDocument(index);
}
},
child: const Text('Scan Document'),
),
],
);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter TWAIN Scanner'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
height: 100,
child: row,
),
DropdownButton(
hint: const Text('Select a scanner'), // 选项1不需要
value: _selectedScanner,
onChanged: (newValue) {
setState(() {
_selectedScanner = newValue;
});
},
items: scannerNames.map((location) {
return DropdownMenuItem(
value: location,
child: Text(location),
);
}).toList(),
),
Expanded(
child: imagePaths.isEmpty
? Image.asset('images/default.png')
: ListView.builder(
itemCount: imagePaths.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: Image.memory(
imagePaths[index],
fit: BoxFit.contain,
), // 对于本地图像,使用 Image.file()
);
},
),
),
],
),
),
);
}
}
更多关于Flutter文档扫描插件flutter_twain_scanner的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter文档扫描插件flutter_twain_scanner的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 flutter_twain_scanner
插件进行文档扫描的示例代码。需要注意的是,flutter_twain_scanner
插件可能不是广泛知名的 Flutter 插件,因此确保你已经正确添加并配置了这个插件。
首先,确保在你的 pubspec.yaml
文件中添加了依赖:
dependencies:
flutter:
sdk: flutter
flutter_twain_scanner: ^最新版本号 # 请替换为实际可用的最新版本号
然后,运行 flutter pub get
来获取依赖。
接下来,在你的 Flutter 应用中使用该插件。以下是一个简单的示例,展示如何打开扫描器并进行文档扫描:
import 'package:flutter/material.dart';
import 'package:flutter_twain_scanner/flutter_twain_scanner.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Twain Scanner Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ScanDocumentScreen(),
);
}
}
class ScanDocumentScreen extends StatefulWidget {
@override
_ScanDocumentScreenState createState() => _ScanDocumentScreenState();
}
class _ScanDocumentScreenState extends State<ScanDocumentScreen> {
File? _scannedFile;
Future<void> _scanDocument() async {
try {
// 打开扫描器
var result = await FlutterTwainScanner.scanDocument();
// 检查扫描结果
if (result != null && result.isNotEmpty) {
setState(() {
_scannedFile = File(result.first); // 假设返回的是文件路径列表,取第一个文件
});
} else {
print("No document scanned.");
}
} catch (e) {
print("Error scanning document: $e");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Scan Document'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _scanDocument,
child: Text('Scan Document'),
),
if (_scannedFile != null)
Image.file(_scannedFile!),
],
),
),
);
}
}
说明:
- 依赖添加:确保在
pubspec.yaml
中添加了flutter_twain_scanner
依赖,并运行flutter pub get
。 - 扫描功能:在
_scanDocument
方法中,使用FlutterTwainScanner.scanDocument()
方法打开扫描器。该方法返回一个文件路径列表(假设),我们取第一个文件路径进行处理。 - UI 显示:在 UI 上,有一个按钮用于触发扫描操作,如果扫描成功,则显示扫描到的图片。
注意事项:
- 插件可用性:由于
flutter_twain_scanner
插件可能不是广泛使用的插件,确保你查阅了最新的文档和示例,了解该插件的具体用法和限制。 - 权限处理:确保你的应用有访问存储和执行扫描操作的权限。这通常在 Android 的
AndroidManifest.xml
和 iOS 的Info.plist
中配置。 - 错误处理:在实际应用中,添加更多的错误处理和用户反馈,以提高应用的健壮性和用户体验。
希望这个示例代码能帮助你理解如何使用 flutter_twain_scanner
插件进行文档扫描。如果有任何问题或需要进一步的帮助,请随时提问。