Flutter机器学习扫描插件fl_mlkit_scanning的使用
Flutter机器学习扫描插件fl_mlkit_scanning的使用
fl_mlkit_scanning
是一个基于 Google ML Kit 实现的快速稳定扫码功能的 Flutter 插件,支持 Android 和 iOS 平台。该插件依赖于 fl_camera
插件来处理相机相关的功能。
使用
1. 添加相机权限
对于 iOS,需要在 Info.plist
文件中添加相机权限:
<key>NSCameraUsageDescription</key>
<string>是否允许FlMlKitScanning使用你的相机?</string>
2. 预览
以下是一个简单的示例,展示如何使用 FlMlKitScanning
进行扫码预览:
import 'package:flutter/material.dart';
import 'package:fl_mlkit_scanning/fl_mlkit_scanning.dart';
import 'package:toast/toast.dart';
class FlMlKitScanningPage extends StatefulWidget {
const FlMlKitScanningPage({Key? key}) : super(key: key);
@override
_FlMlKitScanningPageState createState() => _FlMlKitScanningPageState();
}
class _FlMlKitScanningPageState extends State<FlMlKitScanningPage> {
late FlMlKitScanningController controller;
@override
void initState() {
super.initState();
controller = FlMlKitScanningController();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Fl MlKit Scanning')),
body: FlMlKitScanning(
frequency: 500, // 解析频率,单位为毫秒
camera: controller.camera, // 默认为后摄像头
resolution: CameraResolution.high, // 预览分辨率
autoScanning: false, // 是否自动扫描
overlay: const ScannerLine(), // 显示在预览上层
updateReset: false, // 更新组件时是否重置相机
fit: BoxFit.fitWidth, // 相机预览位置
onFlashChanged: (FlashState state) {
showToast('$state', duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
},
onZoomChanged: (double zoom) {
showToast('Zoom: $zoom', duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
},
uninitialized: Container(
color: Colors.black,
alignment: Alignment.center,
child: const Text('Camera not initialized', style: TextStyle(color: Colors.white)),
),
barcodeFormats: <BarcodeFormat>[BarcodeFormat.qr_code], // 识别类型
onDataChanged: (AnalysisImageModel data) {
final List<Barcode>? barcodes = data.barcodes;
if (barcodes != null && barcodes.isNotEmpty) {
Navigator.of(context).pop(barcodes);
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.toggleFlash(); // 切换闪光灯
},
child: Icon(Icons.flash_on),
),
);
}
}
3. 方法
以下是 FlMlKitScanningController
提供的一些常用方法:
void func() {
// 设置识别码类型
controller.setBarcodeFormat();
// 识别图片字节
controller.scanningImageByte();
// 打开/关闭闪光灯
controller.setFlashMode();
// 相机缩放
controller.setZoomRatio();
// 暂停扫描
controller.pauseScanning();
// 开始扫描
controller.startScanning();
}
示例代码
以下是一个完整的示例项目,展示了如何使用 fl_mlkit_scanning
插件进行扫码和图片识别:
import 'package:example/image_scanning.dart';
import 'package:example/mlkit_scanning.dart';
import 'package:fl_extended/fl_extended.dart';
import 'package:fl_mlkit_scanning/fl_mlkit_scanning.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MaterialApp(
navigatorKey: FlExtended().navigatorKey,
scaffoldMessengerKey: FlExtended().scaffoldMessengerKey,
debugShowCheckedModeBanner: false,
theme: ThemeData.light(useMaterial3: true),
darkTheme: ThemeData.dark(useMaterial3: true),
home: _App(),
title: 'FlMlKitScanning'));
}
class _App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<_App> {
List<Barcode> list = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarText('Fl MlKit Scanning'),
body: Universal(width: double.infinity, children: [
ElevatedText(onPressed: openCamera, text: 'Turn on camera scanning'),
ElevatedText(onPressed: scanImage, text: 'Image scanning'),
const SizedBox(height: 30),
CodeBox(list)
]));
}
void scanImage() {
push(const ImageScanningPage());
}
Future<void> openCamera() async {
bool permission = await getPermission(Permission.camera);
if (permission) {
final List<Barcode>? data = await push(const FlMlKitScanningPage());
if (data != null) {
list = data;
setState(() {});
}
}
}
}
class CodeBox extends StatelessWidget {
const CodeBox(this.list, {super.key, this.expanded = true});
final List<Barcode> list;
final bool expanded;
@override
Widget build(BuildContext context) {
return Universal(
expanded: expanded,
isScroll: expanded,
children: list.builderEntry((MapEntry<int, Barcode> entry) {
return Column(children: [
Text('NO.${entry.key + 1}'),
const SizedBox(height: 6),
Text('value:${entry.value.value}').sizedBox(width: double.infinity),
const SizedBox(height: 6),
Text('type:${entry.value.type}').sizedBox(width: double.infinity),
Text('boundingBox:${entry.value.boundingBox?.size}')
.sizedBox(width: double.infinity),
Text('boundingBox:${entry.value.boundingBox}')
.sizedBox(width: double.infinity),
Text('corners:${entry.value.corners}')
.sizedBox(width: double.infinity),
]);
}));
}
}
class AppBarText extends AppBar {
AppBarText(String text, {super.key})
: super(
elevation: 0,
title: BText(text, fontSize: 18, fontWeight: FontWeight.bold));
}
class TextBox extends StatelessWidget {
final dynamic keyName;
final dynamic value;
const TextBox(this.keyName, this.value, {super.key});
@override
Widget build(BuildContext context) {
return Visibility(
visible: value != null &&
value.toString().isNotEmpty &&
value.toString() != 'null',
child: Container(
margin: const EdgeInsets.all(10),
child: Text('$keyName = $value')));
}
}
Future<bool> getPermission(Permission permission) async {
PermissionStatus status = await permission.status;
if (status.isGranted) {
return true;
} else {
status = await permission.request();
if (!status.isGranted) openAppSettings();
return status.isGranted;
}
}
class ElevatedText extends StatelessWidget {
const ElevatedText({super.key, this.onPressed, required this.text});
final VoidCallback? onPressed;
final String text;
@override
Widget build(BuildContext context) =>
ElevatedButton(onPressed: onPressed, child: Text(text));
}
class ElevatedIcon extends StatelessWidget {
const ElevatedIcon({super.key, this.onPressed, required this.icon});
final VoidCallback? onPressed;
final IconData icon;
@override
Widget build(BuildContext context) =>
ElevatedButton(onPressed: onPressed, child: Icon(icon));
}
以上代码展示了如何使用 fl_mlkit_scanning
插件进行扫码和图片识别,并处理相机权限和结果显示。希望对你有所帮助!
更多关于Flutter机器学习扫描插件fl_mlkit_scanning的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter机器学习扫描插件fl_mlkit_scanning的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用fl_mlkit_scanning
插件进行机器学习扫描的示例代码。这个插件通常用于二维码、条形码扫描等功能,基于Google的ML Kit。
首先,确保你已经在pubspec.yaml
文件中添加了fl_mlkit_scanning
依赖:
dependencies:
flutter:
sdk: flutter
fl_mlkit_scanning: ^0.x.x # 请替换为最新版本号
然后,运行flutter pub get
来获取依赖。
接下来,是一个完整的示例代码,展示了如何使用fl_mlkit_scanning
进行二维码扫描:
import 'package:flutter/material.dart';
import 'package:fl_mlkit_scanning/fl_mlkit_scanning.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ScannerScreen(),
);
}
}
class ScannerScreen extends StatefulWidget {
@override
_ScannerScreenState createState() => _ScannerScreenState();
}
class _ScannerScreenState extends State<ScannerScreen> {
late final BarcodeScannerController _controller = BarcodeScannerController();
final GlobalKey _qrKey = GlobalKey();
@override
void initState() {
super.initState();
_controller.addListener(() {
if (mounted) {
setState(() {});
}
if (_controller.value.data != null) {
_controller.pause();
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Scan Result'),
content: Text(_controller.value.data!),
actions: <Widget>[
TextButton(
child: Text('Close'),
onPressed: () {
Navigator.of(context).pop();
_controller.resume();
},
),
],
),
);
}
});
_controller.initialize().then((_) {
if (!mounted) return;
setState(() {});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (!_controller.value.isInitialized) {
return Center(child: CircularProgressIndicator());
}
return Scaffold(
appBar: AppBar(
title: Text('Barcode Scanner'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 5,
child: CustomPaint(
size: Size.infinite,
painter: CameraPreviewPainter(_controller),
key: _qrKey,
),
),
Expanded(
flex: 1,
child: Center(
child: _controller.value.data == null
? Text('No data captured')
: Text(
'${_controller.value.data!}',
style: TextStyle(color: Colors.red, fontSize: 24),
),
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggleFlash,
tooltip: 'Toggle Flash',
child: Icon(_controller.value.isFlashOn ? Icons.flash_on : Icons.flash_off),
),
);
}
Future<void> _toggleFlash() async {
if (!_controller.value.isFlashAvailable) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Flash is not available on this device')),
);
return;
}
await _controller.toggleFlash();
}
}
class CameraPreviewPainter extends CustomPainter {
final BarcodeScannerController controller;
CameraPreviewPainter(this.controller);
@override
void paint(Canvas canvas, Size size) {
final renderBox = _qrKey.currentContext?.findRenderObject() as RenderBox?;
if (renderBox == null || !controller.value.isPreviewRunning) {
return;
}
final offset = renderBox.localToGlobal(Offset.zero);
final size = renderBox.size;
controller.processImage(
Image.memory(controller.value.previewBytes!)
.toByteData(format: ui.ImageByteFormat.rawRgba)!
.buffer
.asUint8List(),
size.width,
size.height,
);
final paint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 2.0;
controller.value.overlay?.forEach((Rect rect) {
canvas.drawRect(
Rect.fromLTWH(
rect.left + offset.dx,
rect.top + offset.dy,
rect.width,
rect.height,
),
paint,
);
});
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个用于扫描二维码的界面。注意以下几点:
- 初始化BarcodeScannerController:在
initState
方法中初始化BarcodeScannerController
,并添加一个监听器来处理扫描结果。 - 显示扫描结果:如果扫描到数据,显示一个对话框来显示扫描结果,并暂停扫描,直到对话框关闭。
- 自定义Painter:使用
CustomPainter
来在相机预览上绘制扫描框(如果有的话)。 - 控制闪光灯:提供了一个浮动操作按钮来切换闪光灯。
请确保在实际使用中处理错误和权限请求(如相机权限),并根据需要调整UI和逻辑。