processImage method

Future<void> processImage({
  1. required BuildContext context,
  2. required InputImage inputImage,
  3. required bool canProcess,
  4. required bool isBusy,
  5. required Function setBusy,
  6. required Function setText,
  7. required Function updateCustomPaint,
  8. required bool isGS1code,
  9. required int quantity,
  10. required List<GS1Barcode> result,
  11. required Function handleError,
  12. required Function storeValue,
  13. required Function storeCode,
  14. required CameraLensDirection cameraLensDirection,
  15. required BarcodeScanner barcodeScanner,
  16. required ScannerLocalization localizations,
})

Implementation

Future<void> processImage({
  required BuildContext context,
  required InputImage inputImage,
  required bool canProcess,
  required bool isBusy,
  required Function setBusy,
  required Function setText,
  required Function updateCustomPaint,
  required bool isGS1code,
  required int quantity,
  required List<GS1Barcode> result,
  required Function handleError,
  required Function storeValue,
  required Function storeCode,
  required CameraLensDirection cameraLensDirection,
  required BarcodeScanner barcodeScanner,
  required ScannerLocalization localizations,
}) async {
  // Check if processing is allowed
  if (!canProcess) return;

  // Check if another processing is in progress
  if (isBusy) return;

  setBusy(true);

  // Clear previous text state
  setText('');

  // Process the image to detect barcodes
  final barcodes = await barcodeScanner.processImage(inputImage);

  // Check if the input image has valid metadata for size and rotation
  if (inputImage.metadata?.size != null &&
      inputImage.metadata?.rotation != null) {
    // If barcodes are found
    if (barcodes.isNotEmpty) {
      final bloc = context.read<DigitScannerBloc>();

      // Check if the widget is scanning GS1 codes
      if (isGS1code) {
        try {
          // Parse the first barcode using GS1BarcodeParser
          final parser = GS1BarcodeParser.defaultParser();
          final parsedResult =
              parser.parse(barcodes.first.displayValue.toString());

          // Check if the barcode has already been scanned
          final alreadyScanned = bloc.state.barCodes.any((element) =>
              element.elements.entries.last.value.data ==
              parsedResult.elements.entries.last.value.data);

          if (alreadyScanned) {
            // Handle error if the barcode is already scanned
            await handleError(
                localizations.translate(i18.scanner.resourceAlreadyScanned));
          } else if (quantity > result.length) {
            // Store the parsed result if the quantity is greater than result length
            await storeValue(parsedResult);
          } else {
            // Handle error if there is a mismatch in the scanned resource count
            await handleError(localizations
                .translate(i18.scanner.scannedResourceCountMisMatch));
          }
        } catch (e) {
          // Handle error if parsing fails
          await handleError(localizations
              .translate(i18.scanner.scannedResourceCountMisMatch));
        }
      } else {
        // For non-GS1 codes
        if (bloc.state.qrCodes.contains(barcodes.first.displayValue)) {
          // Handle error if the QR code is already scanned
          await handleError(
              localizations.translate(i18.scanner.resourceAlreadyScanned));
          return;
        } else {
          // Store the QR code if not already scanned
          await storeCode(barcodes.first.displayValue.toString());
        }
      }
    }

    // Create a custom painter to draw the detected barcodes
    final painter = BarcodeDetectorPainter(
      barcodes,
      inputImage.metadata!.size,
      inputImage.metadata!.rotation,
      cameraLensDirection,
    );
    updateCustomPaint(CustomPaint(painter: painter));
  } else {
    // Display the number of barcodes found and their raw values
    String text =
        '${localizations.translate(i18.scanner.barCodesFound)}: ${barcodes.length}\n\n';
    for (final barcode in barcodes) {
      text +=
          '${localizations.translate(i18.scanner.barCode)}: ${barcode.rawValue}\n\n';
    }
    setText(text);

    // TODO: set _customPaint to draw boundingRect on top of image
    updateCustomPaint(null);
  }

  // Mark the processing as complete
  setBusy(false);
}