widgetToImageBytes static method

Future<Uint8List> widgetToImageBytes({
  1. required Widget child,
  2. required BuildContext context,
  3. Size? size,
  4. double? pixelRatio,
  5. ImageByteFormat format = ui.ImageByteFormat.png,
  6. Duration delay = Duration.zero,
  7. bool inheritTheme = true,
})

Implementation

static Future<Uint8List> widgetToImageBytes({
  required Widget child,
  required BuildContext context,
  Size? size,
  double? pixelRatio,
  ui.ImageByteFormat format = ui.ImageByteFormat.png,
  Duration delay = Duration.zero,
  bool inheritTheme = true,
}) async {
  final ui.FlutterView view = View.of(context);
  final RenderRepaintBoundary repaintBoundary = RenderRepaintBoundary();
  final PipelineOwner pipelineOwner = PipelineOwner();
  final Size logicalSize = size ?? view.physicalSize / view.devicePixelRatio;

  final RenderView renderView = RenderView(
    view: view,
    child: RenderPositionedBox(child: repaintBoundary),
    configuration: ViewConfiguration(
      size: logicalSize,
      devicePixelRatio: pixelRatio ?? 1.0,
    ),
  );

  int retryCounter = 3;
  bool isDirty = false;
  ui.Image? image;

  final BuildOwner buildOwner = BuildOwner(
    focusManager: FocusManager(),
    onBuildScheduled: () => isDirty = true,
  );

  final rootElement = RenderObjectToWidgetAdapter<RenderBox>(
    container: repaintBoundary,
    child: Directionality(
      textDirection: TextDirection.ltr,
      child: inheritTheme
          ? InheritedTheme.captureAll(
              context,
              MediaQuery(data: MediaQuery.of(context), child: child),
            )
          : child,
    ),
  ).attachToRenderTree(buildOwner);

  pipelineOwner.rootNode = renderView;
  renderView.prepareInitialFrame();

  void buildScope() {
    buildOwner
      ..buildScope(rootElement)
      ..finalizeTree();
    pipelineOwner
      ..flushLayout()
      ..flushCompositingBits()
      ..flushPaint();
  }

  buildScope();

  do {
    isDirty = false;
    image = await repaintBoundary.toImage(
      pixelRatio: pixelRatio ?? (view.physicalSize.width / logicalSize.width),
    );
    await Future.delayed(delay);
    if (isDirty) buildScope();
    retryCounter--;
  } while (isDirty && retryCounter >= 0);
  final ByteData? byteData = await image.toByteData(format: format);
  return byteData!.buffer.asUint8List();
}