capture method

Future<List<ExportedLayer>> capture({
  1. required List<Layer> layers,
  2. required Size editorBodySize,
  3. ProImageEditorConfigs configs = const ProImageEditorConfigs(),
  4. double? pixelRatio,
  5. double? basePixelRatio,
  6. bool applyTransforms = true,
  7. ImageByteFormat format = ui.ImageByteFormat.png,
  8. Future<void> awaitContentReady()?,
})

Captures layers and returns their rendered bytes with layout metadata.

editorBodySize must be the body size the layers were laid out against in the original session — offsets are relative to it.

configs must be the configuration of the session that created the layers, not just any configuration: the size of text, emoji and widget layers is derived from it (textEditor.initFontSize * layer.scale, stickerEditor.initWidth), and configs.theme decides which text theme layer content inherits. Capturing with the default configuration rescales every such layer without reporting anything.

pixelRatio and basePixelRatio control the output resolution and are forwarded to Layer.captureAllLayers. basePixelRatio defaults to configs.imageGeneration.customPixelRatio — the value the editor's own export path passes — so a captured layer matches the resolution of a live-session export.

Layers whose content loads asynchronously — network images, decoded assets, custom WidgetLayers — are not painted yet one frame after mounting, and would be captured blank. Pass awaitContentReady to hold the capture until that content is resolved; it runs after the layers are mounted and is followed by another frame before the capture. Only the caller knows what its layers load, so there is no useful default.

Returns an empty list when layers is empty. A layer that cannot be captured is dropped by Layer.captureAllLayers, so the result can be shorter than layers; compare ExportedLayer.layer against the input to find out which ones. Throws a StateError when no LayerRasterizerHost is mounted, or when the host disappears before the layers are captured, and must not be called during a build — mounting the layers rebuilds the host.

Implementation

Future<List<ExportedLayer>> capture({
  required List<Layer> layers,
  required Size editorBodySize,
  ProImageEditorConfigs configs = const ProImageEditorConfigs(),
  double? pixelRatio,
  double? basePixelRatio,
  bool applyTransforms = true,
  ui.ImageByteFormat format = ui.ImageByteFormat.png,
  Future<void> Function()? awaitContentReady,
}) {
  // Cheap enough to answer before queueing, so an empty request does not wait
  // behind an unrelated capture.
  if (layers.isEmpty) {
    return Future<List<ExportedLayer>>.value(const <ExportedLayer>[]);
  }

  final result = _queue.then(
    (_) => _capture(
      layers: layers,
      editorBodySize: editorBodySize,
      configs: configs,
      pixelRatio: pixelRatio,
      basePixelRatio: basePixelRatio,
      applyTransforms: applyTransforms,
      format: format,
      awaitContentReady: awaitContentReady,
    ),
  );
  // Keep the chain alive after a failed capture so one error does not block
  // every later capture.
  _queue = result.then((_) {}, onError: (_, _) {});
  return result;
}