run method

  1. @override
Future<void> run()
override

the SimpleFrameApp subclass implements application-specific code

Implementation

@override
Future<void> run() async {
  currentState = ApplicationState.running;
  if (mounted) setState(() {});

  try {
    // the image data as a list of bytes that accumulates with each packet
    StatelessWidget meta;

    if (_isAutoExposure) {
      meta = AutoExpImageMetadata(_qualityValues[_qualityIndex].toInt(), _autoExpGainTimes, _autoExpInterval, _meteringValues[_meteringIndex], _exposure, _exposureSpeed, _shutterLimit, _analogGainLimit, _whiteBalanceSpeed);
    }
    else {
      meta = ManualExpImageMetadata(_qualityValues[_qualityIndex].toInt(), _manualShutter, _manualAnalogGain, _manualRedGain, _manualGreenGain, _manualBlueGain);
    }

    try {
      // set up the data response handler for the photos
      _photoStream = RxPhoto(qualityLevel: _qualityValues[_qualityIndex].toInt()).attach(frame!.dataResponse).listen((imageData) {
        // received a whole-image Uint8List with jpeg header and footer included
        _stopwatch.stop();

        // unsubscribe from the image stream now (to also release the underlying data stream subscription)
        _photoStream?.cancel();

        try {
          Image im = Image.memory(imageData);

          // add the size and elapsed time to the image metadata widget
          if (meta is AutoExpImageMetadata) {
            meta.size = imageData.length;
            meta.elapsedTimeMs = _stopwatch.elapsedMilliseconds;
          }
          else if (meta is ManualExpImageMetadata) {
            meta.size = imageData.length;
            meta.elapsedTimeMs = _stopwatch.elapsedMilliseconds;
          }

          _log.fine('Image file size in bytes: ${imageData.length}, elapsedMs: ${_stopwatch.elapsedMilliseconds}');

          setState(() {
            _imageList.insert(0, im);
            _imageMeta.insert(0, meta);
            _jpegBytes.insert(0, imageData);
          });

          currentState = ApplicationState.ready;
          if (mounted) setState(() {});

        } catch (e) {
          _log.severe('Error converting bytes to image: $e');
        }
      });
    } catch (e) {
      _log.severe('Error reading image data response: $e');
      // unsubscribe from the image stream now (to also release the underlying data stream subscription)
      _photoStream?.cancel();
    }

    // send the lua command to request a photo from the Frame
    _stopwatch.reset();
    _stopwatch.start();

    // Send the respective settings for autoexposure or manual
    if (_isAutoExposure) {
      await frame!.sendMessage(TxCameraSettings(
        msgCode: 0x0d,
        qualityIndex: _qualityIndex,
        autoExpGainTimes: _autoExpGainTimes,
        autoExpInterval: _autoExpInterval,
        meteringIndex: _meteringIndex,
        exposure: _exposure,
        exposureSpeed: _exposureSpeed,
        shutterLimit: _shutterLimit,
        analogGainLimit: _analogGainLimit,
        whiteBalanceSpeed: _whiteBalanceSpeed,
      ));
    }
    else {
      await frame!.sendMessage(TxCameraSettings(
        msgCode: 0x0d,
        qualityIndex: _qualityIndex,
        autoExpGainTimes: 0,
        manualShutter: _manualShutter,
        manualAnalogGain: _manualAnalogGain,
        manualRedGain: _manualRedGain,
        manualGreenGain: _manualGreenGain,
        manualBlueGain: _manualBlueGain,
      ));
    }
  }
  catch (e) {
    _log.severe('Error executing application: $e');
  }
}