Flutter图像捕获与处理插件dynamsoft_capture_vision_flutter的使用
Flutter图像捕获与处理插件dynamsoft_capture_vision_flutter的使用
1. Dynamsoft Capture Vision (DCV) 简介
Dynamsoft Capture Vision (DCV) 是一个集成了多个特定功能产品的SDK,包括:
- Dynamsoft Camera Enhancer (DCE):提供相机增强和UI配置API。
- Dynamsoft Barcode Reader (DBR):提供条码解码算法和API。
- Dynamsoft Label Recognizer (DLR):提供标签内容识别算法和API。
- Dynamsoft Document Normalizer (DDN):提供文档扫描算法和API。
注意:当前DCV Flutter版本仅支持条码读取功能。
2. 功能特点
支持多种条码类型
-
一维条码:
- Code 39(包括扩展版)
- Code 93
- Code 128
- Codabar
- Interleaved 2 of 5
- EAN-8
- EAN-13
- UPC-A
- UPC-E
- Industrial 2 of 5
- MSI(Modified Plessey)
- Code 11
-
二维条码:
- QR Code(包括Micro QR Code和Model 1)
- Data Matrix
- PDF417(包括Micro PDF417)
- Aztec Code
- MaxiCode(mode 2-5)
- DotCode
-
其他条码类型:
- GS1 DataBar
- GS1 Composite Code
- Patch Code
- Pharmacode
- 邮政编码
多个条码扫描
库支持同时扫描多个条码。你可以使用 DBRRuntimeSettings.expectedBarcodeCount
来配置预期的条码数量。
高速、高精度和高可读性条码解码
-
模糊条码
-
反色条码
-
变形条码
-
损坏条码
针对不同场景的自定义
SDK设计灵活,可以根据不同的应用场景进行自定义。如果你对当前性能不满意,可以联系官方获取进一步支持。
3. 入门指南
在本指南中,你将逐步学习如何将Dynamsoft Capture Vision Flutter SDK的条码读取功能集成到你的应用中。
4. 示例代码
以下是一个完整的示例demo,展示了如何使用 dynamsoft_capture_vision_flutter
插件来实现条码扫描功能。
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:dynamsoft_capture_vision_flutter/dynamsoft_capture_vision_flutter.dart';
import 'package:flutter_beep/flutter_beep.dart';
import 'package:image_picker/image_picker.dart';
import 'package:vibration/vibration.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 将你的Dynamsoft Barcode Reader许可证密钥放在这里
const String licenseKey =
'DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTEwMTIwMDkzNiIsIm9yZ2FuaXphdGlvbklEIjoiMjAwMDAxIn0=';
// 初始化许可证,以便使用条码读取模块的全部功能
try {
await DCVBarcodeReader.initLicense(licenseKey);
} catch (e) {
print(e);
}
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: '条码读取简单示例',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: '首页'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String? path;
void _startScanning() {
Navigator.push(
context, MaterialPageRoute(builder: (context) => BarcodeScanner()));
}
[@override](/user/override)
void initState() {
super.initState();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView(
children: [
TextButton(
onPressed: _startScanning,
child: Text('开始扫描'),
style: TextButton.styleFrom(backgroundColor: Colors.blue),
),
],
),
);
}
}
class BarcodeScanner extends StatefulWidget {
BarcodeScanner({Key? key}) : super(key: key);
[@override](/user/override)
State<BarcodeScanner> createState() => _BarcodeScannerState();
}
class _BarcodeScannerState extends State<BarcodeScanner>
with WidgetsBindingObserver {
late final DCVBarcodeReader _barcodeReader;
late final DCVCameraEnhancer _cameraEnhancer;
late final ImagePicker _picker;
final DCVCameraView _cameraView = DCVCameraView();
List<BarcodeResult> decodeRes = [];
String? resultText;
String? base64ResultText;
bool faceLens = false;
[@override](/user/override)
void initState() {
super.initState();
WidgetsBinding.instance?.addObserver(this);
_picker = ImagePicker();
_sdkInit();
}
[@override](/user/override)
void dispose() {
WidgetsBinding.instance?.removeObserver(this);
_cameraEnhancer.close();
_barcodeReader.stopScanning();
super.dispose();
}
void _sdkInit() async {
// 创建条码读取器实例
_barcodeReader = await DCVBarcodeReader.createInstance();
_cameraEnhancer = await DCVCameraEnhancer.createInstance();
// 获取条码读取器的当前运行时设置
DBRRuntimeSettings currentSettings = await _barcodeReader.getRuntimeSettings();
// 设置要读取的条码格式
currentSettings.barcodeFormatIds = EnumBarcodeFormat.BF_ONED |
EnumBarcodeFormat.BF_QR_CODE |
EnumBarcodeFormat.BF_PDF417 |
EnumBarcodeFormat.BF_DATAMATRIX;
// 设置预期的条码数量为0,当你不确定要扫描多少个条码时
currentSettings.expectedBarcodeCount = 0;
// 应用新的运行时设置到条码读取器
await _barcodeReader.updateRuntimeSettings(currentSettings);
// 定义扫描区域
_cameraEnhancer.setScanRegion(Region(
regionTop: 30,
regionLeft: 15,
regionBottom: 70,
regionRight: 85,
regionMeasuredByPercentage: 1));
// 启用条码叠加层可见性
_cameraView.overlayVisible = true;
// 设置闪光灯按钮
_cameraView.torchButton = TorchButton(
visible: true,
);
// 设置缩放因子
_cameraEnhancer.setZoomFactor(2.0);
// 启用结果验证
await _barcodeReader.enableResultVerification(true);
// 监听条码结果回调
_barcodeReader.receiveResultStream().listen((List<BarcodeResult>? res) {
if (mounted) {
setState(() {
decodeRes = res ?? [];
});
}
});
// 打开相机
await _cameraEnhancer.open();
// 启用视频条码扫描
_barcodeReader.startScanning();
}
/// 获取列表项
Widget listItem(BuildContext context, int index) {
BarcodeResult res = decodeRes[index];
return ListTileTheme(
textColor: Colors.white,
child: ListTile(
title: Text(res.barcodeFormatString),
subtitle: Text(res.barcodeText),
));
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('条码扫描器'),
),
body: Stack(
children: [
Container(
child: _cameraView,
),
Container(
height: 100,
child: ListView.builder(
itemBuilder: listItem,
itemCount: decodeRes.length,
),
),
Positioned(
top: 150,
left: 25,
child: GestureDetector(
onTap: () {
faceLens = !faceLens;
_cameraEnhancer.selectCamera(faceLens
? EnumCameraPosition.CP_FRONT
: EnumCameraPosition.CP_BACK);
},
child: Image.asset(
'assets/toggle_lens.png',
width: 48,
height: 48,
),
),
),
Positioned(
bottom: 20,
left: MediaQuery.of(context).size.width / 2 - 80,
child: Column(
children: [
Container(
width: 160,
child: TextButton(
onPressed: () => _pickImage(ImageSource.gallery),
child: Text('选择照片'),
style: TextButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: Colors.blue),
),
),
Container(
width: 160,
child: TextButton(
onPressed: () => _pickImage(ImageSource.camera),
child: Text('拍照'),
style: TextButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: Colors.blue),
),
),
],
),
)
],
));
}
void _pickImage(ImageSource source) async {
final XFile? image = await _picker.pickImage(source: source);
final path = image?.path;
if (path != null) {
final result = await _barcodeReader.decodeFile(path);
if (await Vibration.hasVibrator() ?? false) {
Vibration.vibrate();
}
FlutterBeep.beep();
if (result != null && result.isNotEmpty) {
resultText = result[0].barcodeText;
final bytes = result[0].barcodeBytes;
base64ResultText = utf8.decode(bytes);
decodeRes.addAll(result);
}
}
setState(() {});
}
[@override](/user/override)
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
switch (state) {
case AppLifecycleState.resumed:
_barcodeReader.startScanning();
_cameraEnhancer.open();
break;
case AppLifecycleState.inactive:
_cameraEnhancer.close();
_barcodeReader.stopScanning();
break;
case AppLifecycleState.detached:
case AppLifecycleState.hidden:
case AppLifecycleState.paused:
break;
default:
break;
}
}
}
更多关于Flutter图像捕获与处理插件dynamsoft_capture_vision_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter图像捕获与处理插件dynamsoft_capture_vision_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用dynamsoft_capture_vision_flutter
插件进行图像捕获与处理的示例代码。这个插件通常用于从摄像头捕获图像并进行一些基本的图像处理。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加dynamsoft_capture_vision_flutter
依赖:
dependencies:
flutter:
sdk: flutter
dynamsoft_capture_vision_flutter: ^最新版本号 # 请替换为实际最新版本号
然后运行flutter pub get
来安装依赖。
2. 配置Android权限
由于图像捕获涉及到摄像头权限,你需要在AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" /> # 如果需要音频
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
3. 请求权限(如果需要)
在Flutter代码中,你可能需要请求这些权限。这里是一个简单的权限请求示例:
import 'package:permission_handler/permission_handler.dart';
Future<void> requestPermissions() async {
var status = await Permission.camera.status;
if (!status.isGranted) {
Map<Permission, PermissionStatus> permissions = await Permission.camera
.request();
status = permissions[Permission.camera]!;
}
if (!status.isGranted) {
// 处理权限被拒绝的情况
return;
}
}
4. 使用插件捕获和处理图像
以下是一个简单的Flutter应用示例,展示了如何使用dynamsoft_capture_vision_flutter
插件来捕获和处理图像:
import 'package:flutter/material.dart';
import 'package:dynamsoft_capture_vision_flutter/dynamsoft_capture_vision_flutter.dart';
import 'dart:typed_data';
import 'dart:ui' as ui;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CapturePage(),
);
}
}
class CapturePage extends StatefulWidget {
@override
_CapturePageState createState() => _CapturePageState();
}
class _CapturePageState extends State<CapturePage> {
late DynamsoftCaptureVision _dynamsoftCaptureVision;
Uint8List? _capturedImage;
@override
void initState() {
super.initState();
_dynamsoftCaptureVision = DynamsoftCaptureVision.instance;
_dynamsoftCaptureVision.init();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dynamsoft Capture Vision Flutter'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_capturedImage == null
? Text('No image captured yet.')
: Image.memory(_capturedImage!),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
Uint8List? imageBytes = await _captureImage();
if (imageBytes != null) {
setState(() {
_capturedImage = imageBytes;
});
}
},
child: Text('Capture Image'),
),
],
),
),
);
}
Future<Uint8List?> _captureImage() async {
try {
var result = await _dynamsoftCaptureVision.captureImage();
if (result != null && result.isSuccess) {
var imageBytes = result.imageBytes;
return imageBytes;
}
} catch (e) {
print('Error capturing image: $e');
}
return null;
}
@override
void dispose() {
_dynamsoftCaptureVision.dispose();
super.dispose();
}
}
5. 运行应用
确保你的设备或模拟器有摄像头权限,然后运行你的Flutter应用。你应该能够看到一个按钮,点击按钮后,会从摄像头捕获图像并显示在页面上。
注意事项
- 确保你已经正确配置了插件的依赖和权限。
- 插件的版本号可能会更新,请查阅最新的文档和示例代码。
- 插件可能会有一些特定的配置选项,你可以查阅插件的官方文档来获取更多信息。
这个示例展示了基本的图像捕获功能,你可以根据需要进行进一步的图像处理或分析。