(颤动)我的扫描页面(EAN-13)根本不起作用,我不知道为什么

(FLUTTER) My Scan Page(EAN-13), Doesn't Work at All, and I Don't Know Why

提问人:Shi Huang 提问时间:11/13/2023 更新时间:11/13/2023 访问量:32

问:

我正在使用 Flutter 开发一个应用程序,我是新手。应用程序中的一个页面旨在扫描条形码,我目前正在使用 EAN-13 进行测试。连接到手机时,相机可以正常打开,但无论我如何调整它,当相机扫描条形码时都没有反应。我已经为此工作了一天,没有任何进展。有人可以帮我确定我的代码可能有什么问题吗?

谢谢:)

...
...
...
import 'package:camera/camera.dart';
import 'package:google_ml_kit/google_ml_kit.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() => runApp(Davascan());

class Davascan extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'test',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ScanPage(),
    );
  }
}

class ScanPage extends StatefulWidget {
  @override
  _ScanPageState createState() => _ScanPageState();
}

class _ScanPageState extends State<ScanPage> {
  CameraController? cameraController;
  late List<CameraDescription> cameras;
  late CameraDescription firstCamera;
  bool isCameraInitialized = false;
  bool isPermissionGranted = false;
  String barcode = '';

  @override
  void initState() {
    super.initState();
    initializeCamera();
  }
///////////////////////////////////////////////////////////////////////////////
  void navigateToProductDetail(String productSn) async {
  final url = Uri.parse('http://dafa.mid.com.tw/api/product/$productSn');
  try {
    final response = await http.get(url);
    if (response.statusCode == 200 && response.body.isNotEmpty) {
      final productDetails = json.decode(response.body);
      
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => Davascanlist(productDetails),
        ),
      );
    } else {
      
      showAlertDialog('123', '123');
    }
  } catch (e) {
    showAlertDialog('456', '456:$e');
  }
}

void showAlertDialog(String title, String content) {
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text(title),
        content: Text(content),
        actions: <Widget>[
          TextButton(
            child: Text('test'),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
        ],
      );
    },
  );
}
/////////////////////////////////////////////////////////////////////////////////////////////
  Future<void> initializeCamera() async {
    cameras = await availableCameras();
    firstCamera = cameras.first;

    cameraController = CameraController(
      firstCamera,
      ResolutionPreset.high,
    );

    await cameraController!.initialize().then((_) {
      if (!mounted) return;
      setState(() {
        isCameraInitialized = true;
         startBarcodeScanStream();  
      });
    });

    final status = await Permission.camera.request();
    setState(() => isPermissionGranted = status == PermissionStatus.granted);
  }
/////////////////////////////////////////////////////////////////////////////////////////////////
  void startBarcodeScanStream() async {
  if (isPermissionGranted && isCameraInitialized) {
    cameraController!.startImageStream((CameraImage image) async {
      final WriteBuffer allBytes = WriteBuffer();
      for (Plane plane in image.planes) {
        allBytes.putUint8List(plane.bytes);
      }
      final bytes = allBytes.done().buffer.asUint8List();

      final Size imageSize = Size(image.width.toDouble(), image.height.toDouble());

      final InputImageRotation imageRotation = InputImageRotation.Rotation_0deg;

      final InputImageFormat inputImageFormat = InputImageFormatMethods.fromRawValue(image.format.raw) ?? InputImageFormat.NV21;

      final List<InputImagePlaneMetadata> planeData = image.planes.map(
        (Plane plane) {
          return InputImagePlaneMetadata(
            bytesPerRow: plane.bytesPerRow,
            height: plane.height,
            width: plane.width,
          );
        },
      ).toList();

      final InputImageData inputImageData = InputImageData(
        size: imageSize,
        imageRotation: imageRotation,
        inputImageFormat: inputImageFormat,
        planeData: planeData,
      );

      final InputImage inputImage = InputImage.fromBytes(bytes: bytes, inputImageData: inputImageData);

      final barcodeScanner = GoogleMlKit.vision.barcodeScanner([
        BarcodeFormat.ean13, //EAN-13
      ]);

      final List<Barcode> barcodes = await barcodeScanner.processImage(inputImage);
      
      for (Barcode barcode in barcodes) {
        final String rawValue = barcode.value.displayValue ?? ''; // The barcode value
        if (rawValue.isNotEmpty) {
          setState(() {
            this.barcode = rawValue;
          });
          
          navigateToProductDetail(rawValue);
          // Stop scanning after the first barcode is found
          cameraController!.stopImageStream();
          break;
        }
      }
    });
  }
}

//////////////////////////////////////////////////////////////////////////////////
  Future<void> fetchProductInfo(String barcode) async {
    var url = Uri.parse('http://dafa.mid.com.tw/api/product/$barcode');
    try {
      var response = await http.get(url);
      if (response.statusCode == 200) {
        var productInfo = json.decode(response.body);
        // Do something with the product info
        // For example, navigate to a new screen with the product info
      } else {
        setState(() => this.barcode = 'Failed to load product info');
      }
    } catch (e) {
      setState(() => this.barcode = 'Error retrieving product info: $e');
    }
  }

  @override
  void dispose() {
    cameraController?.dispose();
    super.dispose();
  }
///////////////////////////////////////////////////////////////////
  @override
  Widget build(BuildContext context) {
    var scanArea = MediaQuery.of(context).size.width * 0.8;
    var scanAreaHeight = scanArea * 0.65; // GTN-13 
    return Scaffold(
      appBar: AppBar(
        title: Text('TEST'),
        backgroundColor: Color.fromARGB(255, 179, 18, 6),
      ),
      body: isCameraInitialized
          ? Stack(
              fit: StackFit.expand,
              children: <Widget>[
                CameraPreview(cameraController!),
                Container(
                  alignment: Alignment.center,
                  child: Container(
                    width: scanArea,
                    height: scanAreaHeight,
                    decoration: BoxDecoration(
                      border: Border.all(
                        color: Colors.red,
                        width: 3.0,
                      ),
                    ),
                  ),
                ),
                Container(
                  alignment: Alignment.center,
                  child: CustomPaint(
                    size: Size(scanArea, scanAreaHeight),
                    painter: OverlayPainter(scanArea: scanArea, scanAreaHeight: scanAreaHeight),
                  ),
                ),
              ],
            )
          : Center(child: CircularProgressIndicator()),
    );
  }
}

class ProductPage extends StatelessWidget {
  final Map productInfo;

  ProductPage(this.productInfo);

  @override
  Widget build(BuildContext context) {
    String imageUrl = productInfo['p_pic'] ?? 'https://via.placeholder.com/150';
    return Scaffold(
      appBar: AppBar(
        title: Text(productInfo['p_name']),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Image.network(imageUrl, fit: BoxFit.cover),
            Text('stackOverFlow: ${productInfo['p_name']}', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
            Text('stackOverFlow: ${productInfo['p_unit']}', style: TextStyle(fontSize: 18)),
            Text('stackOverFlow: ${productInfo['p_storage']}', style: TextStyle(fontSize: 18)),
            Text('stackOverFlow: ${productInfo['p_barcode']}', style: TextStyle(fontSize: 18)),
            Text('stackOverFlow: ${productInfo['p_store_code']}', style: TextStyle(fontSize: 18)),
            Text('stackOverFlow: ${productInfo['p_stock']}', style: TextStyle(fontSize: 18)),
            Text('stackOverFlow: ${productInfo['p_price']}元', style: TextStyle(fontSize: 18)),
            Text('stackOverFlow: ${productInfo['p_price2']}元', style: TextStyle(fontSize: 18)),
            Text('stackOverFlow: ${productInfo['p_status'] == "1" ? "test" : "test"}', style: TextStyle(fontSize: 18)),
            
          ],
        ),
      ),
    );
  }
}

class OverlayPainter extends CustomPainter {
  final double scanArea;
  final double scanAreaHeight;

  OverlayPainter({required this.scanArea, required this.scanAreaHeight});

  @override
  void paint(Canvas canvas, Size size) {
    final rect = Rect.fromLTWH(
      size.width / 2 - scanArea / 2,
      size.height / 2 - scanAreaHeight / 2,
      scanArea,
      scanAreaHeight,
    );

    final Path background = Path()
      ..addRect(Rect.fromLTRB(0, 0, size.width, size.height))
      ..addRect(rect)
      ..fillType = PathFillType.evenOdd;

    final Paint paint = Paint()..color = Colors.black.withOpacity(0.5);
    canvas.drawPath(background, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

我已经尝试了所有我能尝试的东西,包括谷歌搜索和咨询 ChatGPT。对于颤振初学者来说,这是一项具有挑战性的任务。我还附上了我的 pubspec.yaml 文件以供参考

name: flutter_application_1
description: A new Flutter project.

publish_to: 'none' 


version: 1.0.0+1

environment:
  sdk: '>=3.1.5 <4.0.0'


dependencies:
  flutter:
    sdk: flutter
  google_maps_flutter: ^2.0.10
  permission_handler: ^11.0.1
  url_launcher: ^6.0.12
  barcode_scan2: ^4.1.4
  http: ^0.13.3
  camera: ^0.9.4+5
  google_ml_kit: ^0.7.2
  sqflite: ^2.0.0+3
  path_provider: ^2.0.2

  cupertino_icons: ^1.0.2

dev_dependencies:
  flutter_test:
    sdk: flutter

  
  flutter_lints: ^2.0.0

flutter:

  uses-material-design: true

  assets:
     - images/
     - txt/


Flutter 条码扫描器 EAN-13

评论


答: 暂无答案