Flutter条形码扫描插件google_mlkit_barcode_scanning的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter条形码扫描插件google_mlkit_barcode_scanning的使用

Google’s ML Kit Barcode Scanning for Flutter

Pub Version analysis Star on Github License: MIT

这是一个Flutter插件,用于使用Google的ML Kit Barcode Scanning来读取大多数标准条形码格式编码的数据。

注意事项

在继续或发布新的问题之前,请务必阅读以下内容:

  1. 平台支持:Google的ML Kit仅适用于移动平台(iOS和Android应用程序)。Web或其他平台不受支持。
  2. 维护者:此插件不是由Google赞助或维护的。作者是热衷于机器学习的开发者,他们希望将Google的原生API暴露给Flutter。
  3. 平台通道:该插件使用Flutter平台通道与原生平台通信。所有机器学习处理都是通过Google的原生API完成的。
  4. 问题报告:在提交新问题之前,请确保问题不是由于Google的原生示例应用引起的。

Requirements

iOS

  • 最低iOS部署目标:15.5.0
  • Xcode 15.3.0 或更新版本
  • Swift 5
  • 排除32位架构(i386 和 armv7),仅支持64位架构(x86_64 和 arm64)

在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

Android

  • minSdkVersion: 21
  • targetSdkVersion: 33
  • compileSdkVersion: 34

Usage

Barcode scanning

创建 InputImage 实例

创建一个 InputImage 实例,参考 官方文档

final InputImage inputImage;

创建 BarcodeScanner 实例

final List<BarcodeFormat> formats = [BarcodeFormat.all, ...];
final barcodeScanner = BarcodeScanner(formats: formats);

处理图像

final List<Barcode> barcodes = await barcodeScanner.processImage(inputImage);

for (Barcode barcode in barcodes) {
  final BarcodeType type = barcode.type;
  final Rect boundingBox = barcode.boundingBox;
  final String? displayValue = barcode.displayValue;
  final String? rawValue = barcode.rawValue;

  // See API reference for complete list of supported types
  switch (type) {
    case BarcodeType.wifi:
      final barcodeWifi = barcode.value as BarcodeWifi;
      break;
    case BarcodeType.url:
      final barcodeUrl = barcode.value as BarcodeUrl;
      break;
  }
}

释放资源

barcodeScanner.close();

示例应用

你可以在这里找到示例应用:example app

完整示例Demo

下面是一个完整的示例应用,展示了如何使用 google_mlkit_barcode_scanning 插件进行条形码扫描。

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  google_mlkit_barcode_scanning: ^latest_version
  image_picker: ^latest_version

main.dart

import 'package:flutter/material.dart';
import 'package:google_mlkit_barcode_scanning/google_mlkit_barcode_scanning.dart';
import 'package:image_picker/image_picker.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BarcodeScannerPage(),
    );
  }
}

class BarcodeScannerPage extends StatefulWidget {
  @override
  _BarcodeScannerPageState createState() => _BarcodeScannerPageState();
}

class _BarcodeScannerPageState extends State<BarcodeScannerPage> {
  final BarcodeScanner _barcodeScanner = BarcodeScanner();
  List<Barcode> _barcodes = [];
  bool _isBusy = false;
  final ImagePicker _picker = ImagePicker();

  Future<void> _scanBarcodeFromImage() async {
    setState(() {
      _isBusy = true;
      _barcodes.clear();
    });

    final pickedFile = await _picker.pickImage(source: ImageSource.camera);
    if (pickedFile == null) {
      setState(() {
        _isBusy = false;
      });
      return;
    }

    final inputImage = InputImage.fromFilePath(pickedFile.path);
    final List<Barcode> barcodes = await _barcodeScanner.processImage(inputImage);

    setState(() {
      _barcodes = barcodes;
      _isBusy = false;
    });
  }

  @override
  void dispose() {
    _barcodeScanner.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Barcode Scanner'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _isBusy ? null : _scanBarcodeFromImage,
              child: Text('Scan Barcode from Camera'),
            ),
            SizedBox(height: 20),
            Expanded(
              child: _barcodes.isEmpty
                  ? Text('No barcodes found.')
                  : ListView.builder(
                      itemCount: _barcodes.length,
                      itemBuilder: (context, index) {
                        final barcode = _barcodes[index];
                        return ListTile(
                          title: Text('Type: ${barcode.type}'),
                          subtitle: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text('Display Value: ${barcode.displayValue ?? 'N/A'}'),
                              Text('Raw Value: ${barcode.rawValue ?? 'N/A'}'),
                            ],
                          ),
                        );
                      },
                    ),
            ),
          ],
        ),
      ),
    );
  }
}

这个示例应用允许用户从相机拍摄照片并识别其中的条形码。识别到的条形码信息会显示在屏幕上。希望这个示例能帮助你更好地理解和使用 google_mlkit_barcode_scanning 插件。


更多关于Flutter条形码扫描插件google_mlkit_barcode_scanning的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter条形码扫描插件google_mlkit_barcode_scanning的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用google_mlkit_barcode_scanning插件进行条形码扫描的示例代码。这个示例包括如何设置插件、打开相机进行条形码扫描以及处理扫描结果。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加google_mlkit_barcode_scanning依赖:

dependencies:
  flutter:
    sdk: flutter
  google_mlkit_barcode_scanning: ^0.18.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

2. 配置Android权限

android/app/src/main/AndroidManifest.xml中添加相机权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

3. 创建条形码扫描页面

接下来,创建一个新的Flutter页面用于条形码扫描。以下是一个简单的示例:

import 'package:flutter/material.dart';
import 'package:google_mlkit_barcode_scanning/google_mlkit_barcode_scanning.dart';
import 'package:camera/camera.dart';

class BarcodeScannerPage extends StatefulWidget {
  @override
  _BarcodeScannerPageState createState() => _BarcodeScannerPageState();
}

class _BarcodeScannerPageState extends State<BarcodeScannerPage> {
  late List<CameraDescription> cameras;
  late CameraController? controller;
  final BarcodeScannerOptions options = BarcodeScannerOptions(
    beepOnScan: true,
    useFrontCamera: false,
    tryHarder: true,
    torchEnabled: false,
    autoFocusMode: AutoFocusMode.continuous,
  );
  BarcodeScanner? scanner;
  String? resultText;

  @override
  void initState() {
    super.initState();
    availableCameras().then((availableCameras) {
      cameras = availableCameras;
      if (cameras.isEmpty) {
        return;
      }
      controller = new CameraController(
        cameras[0],
        ResolutionPreset.high,
        enableAudio: true,
      );
      controller!.initialize().then((_) {
        if (mounted) {
          setState(() {});
        }
        scanner = GoogleMlKitBarcodeScanner(options: options);
        controller!.startImageStream((CameraImage image) async {
          final inputImage = InputImage.fromBytes(
            bytes: image.planes.map((plane) {
              return plane.bytes;
            }).reduce((value, element) => value + element.lengthInBytes),
            size: Size(image.width, image.height),
            format: image.format.raw,
            planeData: image.planes.map((plane) {
              return InputImagePlaneMetadata(
                bytesPerRow: plane.bytesPerRow,
                height: plane.height,
                width: plane.width,
              );
            }).toList(),
          );
          try {
            final result = await scanner!.scanBarcodes(inputImage);
            if (result.isNotEmpty && mounted) {
              setState(() {
                resultText = result[0].rawValue;
              });
              // 停止相机流并处理结果
              controller!.stopImageStream();
              Navigator.pop(context, resultText);
            }
          } catch (e) {
            print(e);
          }
        });
      }).catchError((error) {
        print("Error: ${error.message}");
      });
    }).catchError((error) {
      print("Error: ${error.message}");
    });
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Barcode Scanner'),
      ),
      body: cameras.isEmpty
          ? Center(
              child: Text(
                'No cameras found!',
                style: TextStyle(color: Colors.red),
              ))
          : AspectRatio(
              aspectRatio: controller!.value.aspectRatio,
              child: CameraPreview(controller!)),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          if (!controller!.value.isStreamingImages) {
            await controller!.startImageStream((CameraImage image) async {
              // This will be called when an image is available from the camera.
            });
          } else {
            await controller!.stopImageStream();
          }
        },
        tooltip:
            'Start/Stop camera preview',
        child: Icon(controller!.value.isStreamingImages ? Icons.stop : Icons.play_arrow),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      bottomSheet: resultText != null
          ? Container(
              padding: EdgeInsets.all(16.0),
              color: Colors.white,
              child: Center(
                child: Text(
                  'Scanned Barcode: $resultText',
                  style: TextStyle(fontSize: 20),
                ),
              ))
          : null,
    );
  }
}

4. 使用条形码扫描页面

在你的主应用代码中,导航到BarcodeScannerPage

import 'package:flutter/material.dart';
import 'barcode_scanner_page.dart';  // 假设你保存上面的代码到这个文件

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Barcode Scanner'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => BarcodeScannerPage()),
              );
            },
            child: Text('Scan Barcode'),
          ),
        ),
      ),
    );
  }
}

这个示例代码展示了如何使用google_mlkit_barcode_scanning插件来扫描条形码。注意,在实际应用中,你可能需要添加更多的错误处理和UI优化。

回到顶部