capture method

request a photo from Frame

Implementation

Future<(Uint8List, ImageMetadata)> capture() async {
  try {
    // save a snapshot of the image metadata (camera settings) to show under the image
    ImageMetadata meta;

    // freeze the quality, resolution and pan for this capture
    var currQualIndex = qualityIndex;
    var currRes = resolution;
    var currPan = pan;

    if (_isAutoExposure) {
      meta = AutoExpImageMetadata(
          quality: qualityValues[currQualIndex],
          resolution: currRes,
          pan: currPan,
          metering: meteringValues[meteringIndex],
          exposure: exposure,
          exposureSpeed: exposureSpeed,
          shutterLimit: shutterLimit,
          analogGainLimit: analogGainLimit,
          whiteBalanceSpeed: whiteBalanceSpeed,
          rgbGainLimit: rgbGainLimit);
    }
    else {
      meta = ManualExpImageMetadata(
          quality: qualityValues[currQualIndex],
          resolution: currRes,
          pan: currPan,
          shutter: manualShutter,
          analogGain: manualAnalogGain,
          redGain: manualRedGain,
          greenGain: manualGreenGain,
          blueGain: manualBlueGain);
    }

    // if we've saved the header from a previous photo, we can request the raw data without the header
    bool requestRaw = RxPhoto.hasJpegHeader(qualityValues[currQualIndex], currRes);

    _stopwatch.reset();
    _stopwatch.start();

    // send the lua command to request a photo from the Frame based on the current settings
    final captureSettings = TxCaptureSettings(
      resolution: currRes,
      qualityIndex: currQualIndex,
      pan: currPan,
      raw: requestRaw,
    );

    await frame!.sendMessage(0x0d, captureSettings.pack());

    // synchronously await the image response (and add jpeg header if necessary)
    Uint8List imageData = await RxPhoto(quality: qualityValues[currQualIndex], resolution: currRes, isRaw: requestRaw, upright: upright).attach(frame!.dataResponse).first;

    // received a whole-image Uint8List with jpeg header included
    _stopwatch.stop();

    // 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}, ${((imageData.length / 1024.0) / (_stopwatch.elapsedMilliseconds / 1000.0)).toStringAsFixed(2)} kB/s');

    return (imageData, meta);

  } catch (e) {
    _log.severe('Error executing application: $e');
    rethrow;
  }
}