首页 > 解决方案 > 如何使用图像流(颤振)创建条形码扫描仪

问题描述

我想使用 Flutter/Dart 创建一个 Android 应用程序,它在移动屏幕的上半部分显示当前相机流,在下半部分显示条形码的结果。这是我想要的: 截图

我当前的代码是:


import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'dart:async';
import 'package:firebase_ml_vision/firebase_ml_vision.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';

final BarcodeDetector _barcodeDetector =
    FirebaseVision.instance.barcodeDetector();
String data = 'EMPTY DATA';

class ScanScreen extends StatefulWidget {
  static String id = 'scan_screen';
  //final CameraDescription camera = cameras.first;
  @override
  _ScanScreenState createState() => _ScanScreenState();
}

class _ScanScreenState extends State<ScanScreen> {
  CameraController _controller;
  Future<void> _initializeControllerFuture;
  CameraImage _savedImage;
  bool _cameraInitialized = false;
  void _initializeCamera() async {
    List<CameraDescription> cameras = await availableCameras();

    _controller = CameraController(
      cameras.first,
      ResolutionPreset.medium,
    );
    _initializeControllerFuture = _controller.initialize().then((_) async {
      // Start ImageStream
      await _controller
          .startImageStream((CameraImage image) => _processCameraImage(image));
//      setState(() {
//        _cameraInitialized = true;
//      });
    });
  }

  Future<String> readBarcode(CameraImage image) async {
      FirebaseVisionImageMetadata firebaseVisionImageMetadata =
          FirebaseVisionImageMetadata(
        rawFormat: image.format.raw,
        size: Size(image.width.toDouble(), image.height.toDouble()),
        rotation: ImageRotation.rotation0,
        planeData: image.planes
            .map(
              (plane) => FirebaseVisionImagePlaneMetadata(
                bytesPerRow: plane.bytesPerRow,
                height: plane.height,
                width: plane.width,
              ),
            )
            .toList(),
      );
      try{
      var barcode = await _barcodeDetector.detectInImage(
        FirebaseVisionImage.fromBytes(
          _concatenatePlanes(image.planes),
          firebaseVisionImageMetadata,
        ),
      );
      if (barcode != null && barcode.length > 0) {
        print(barcode.toString()+barcode.first.toString());
        return barcode.toString();
      } else {
        print('no barcode');
        return 'no barcode found';
      }
    } catch (e) {
      print(e);
      return 'error';
    }
  }

  void _processCameraImage(CameraImage image) async {
    _savedImage = image;
    await readBarcode(image).then((String result) {
      setState(() {
        print(result);
//data=result;
      });
    });
  }

  Uint8List _concatenatePlanes(List<Plane> planes) {
    final WriteBuffer allBytes = WriteBuffer();
    planes.forEach((plane) => allBytes.putUint8List(plane.bytes));
    return allBytes.done().buffer.asUint8List();
  }

  @override
  void initState() {
    super.initState();
    _initializeCamera();
    // startBarcodeScanStream();
  }

  startBarcodeScanStream() async {
    FlutterBarcodeScanner.getBarcodeStreamReceiver(
            "#ff6666", "Cancel", true, ScanMode.BARCODE)
        .listen((barcode) => print(barcode));
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final deviceRatio = size.width / size.height;

    return Scaffold(
      appBar: AppBar(
        title: Text('Scan Product'),
      ),
      body: Container(
        color: Colors.black,
        child: Column(
          children: [
            Expanded(
              flex: 2,
              child: Stack(
                children: [
                  MaterialApp(
                    home: Padding(
                      padding:
                          EdgeInsets.symmetric(horizontal: 7.0, vertical: 10.0),
                      child: AspectRatio(
                        aspectRatio: _controller.value.aspectRatio,
                        child: CameraPreview(_controller),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            SizedBox(
              height: 10.0,
            ),
            Expanded(
              flex: 2,
              child: Container(
                color: Colors.deepPurple,
                child: Text(
                  data,
                  style: TextStyle(
                    fontSize: 50.0,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

我得到的只是条形码值的“条形码”实例。

标签: androidfirebaseflutterbarcode-scannerfirebase-machine-learning

解决方案


推荐阅读