process method

FutureOr<void> process(
  1. (Uint8List, ImageMetadata) photo
)

The vision pipeline to run when a photo is captured

Implementation

FutureOr<void> process((Uint8List, ImageMetadata) photo) async {
  var imageData = photo.$1;
  var meta = photo.$2;

  try {
    // update Widget UI
    // For the widget we rotate it upon display with a transform, not changing the source image
    Image im = Image.memory(
      imageData,
      gaplessPlayback: true,
    );

    setState(() {
      _image = im;
      _imageMeta = meta;
    });

    // Perform vision processing pipeline on the current image
    try {
      // will sometimes throw an Exception on decoding, but doesn't return null
      _stopwatch.reset();
      _stopwatch.start();
      img.Image im = img.decodeJpg(imageData)!;
      _stopwatch.stop();
      _log.fine(
          () => 'Jpeg decoding took: ${_stopwatch.elapsedMilliseconds} ms');

      // Android mlkit needs NV21 InputImage format
      // iOS mlkit needs bgra8888 InputImage format
      // In both cases orientation metadata is passed to mlkit, so no need to bake in a rotation
      _stopwatch.reset();
      _stopwatch.start();
      // Frame images are rotated 90 degrees clockwise
      InputImage mlkitImage = ImageMlkitConverter.imageToMlkitInputImage(
          im, InputImageRotation.rotation90deg);
      _stopwatch.stop();
      _log.fine(() =>
          'NV21/BGRA8888 conversion took: ${_stopwatch.elapsedMilliseconds} ms');

      // run the text recognizer
      _stopwatch.reset();
      _stopwatch.start();
      _codesFound = await _barcodeScanner.processImage(mlkitImage);
      _stopwatch.stop();
      _log.fine(() =>
          'Barcode scanning took: ${_stopwatch.elapsedMilliseconds} ms');

      // display to Frame if a barcode has been found
      if (_codesFound.isNotEmpty) {
        List<String> frameText = [];
        // loop over any codes found
        for (Barcode barcode in _codesFound) {
          if (barcode.type case BarcodeType.url) {
            final barcodeUrl = barcode.value as BarcodeUrl;
            frameText.add('${barcode.type.name}: ${barcodeUrl.url}');
          } else {
            frameText.add('${barcode.type.name}: ${barcode.displayValue}');
          }
        }

        _log.fine(() => 'Codes found: $frameText');

        // print the detected barcodes on the Frame display
        await frame!.sendMessage(TxPlainText(
            msgCode: 0x0a,
            text:
                TextUtils.wrapText(frameText.join('\n'), 640, 4).join('\n')));
      }
    } catch (e) {
      _log.severe('Error converting bytes to image: $e');
    }

    // indicate that we're done processing
    _processing = false;
  } catch (e) {
    _log.severe('Error processing photo: $e');
    // TODO rethrow;?
  }
}