createImageFromWidget static method

Future<Uint8List?> createImageFromWidget(
  1. BuildContext context,
  2. Widget widget,
  3. {Duration? wait,
  4. Size? logicalSize,
  5. Size? imageSize,
  6. TextDirection textDirection = TextDirection.ltr}
)

Generats an image from widget. Set Duration if you are using async widgets or widget that take time to fully build. logicalSize Size is the size of the device the widget is made into. imageSize Size is the size of image generated. sets the TextDirection.

Implementation

static Future<Uint8List?> createImageFromWidget(
  BuildContext context,
  Widget widget, {
  Duration? wait,
  Size? logicalSize,
  Size? imageSize,
  TextDirection textDirection = TextDirection.ltr,
}) async {
  final RenderRepaintBoundary repaintBoundary = RenderRepaintBoundary();

  logicalSize ??=
      View.of(context).physicalSize / View.of(context).devicePixelRatio;
  imageSize ??= View.of(context).physicalSize;
  assert(logicalSize.aspectRatio == imageSize.aspectRatio);
  final RenderView renderView = RenderView(
    view: WidgetsFlutterBinding.ensureInitialized()
        .platformDispatcher
        .views
        .first,
    child: RenderPositionedBox(
      alignment: Alignment.center,
      child: repaintBoundary,
    ),
    configuration: ViewConfiguration(
      size: logicalSize,
      devicePixelRatio: 1.0,
    ),
  );

  final PipelineOwner pipelineOwner = PipelineOwner();
  final BuildOwner buildOwner = BuildOwner();

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

  final RenderObjectToWidgetElement<RenderBox> rootElement =
      RenderObjectToWidgetAdapter<RenderBox>(
    container: repaintBoundary,
    child: Directionality(
      textDirection: textDirection,
      child: IntrinsicHeight(child: IntrinsicWidth(child: widget)),
    ),
  ).attachToRenderTree(buildOwner);

  buildOwner.buildScope(rootElement);

  if (wait != null) {
    await Future.delayed(wait);
  }

  buildOwner
    ..buildScope(rootElement)
    ..finalizeTree();

  pipelineOwner
    ..flushLayout()
    ..flushCompositingBits()
    ..flushPaint();

  final ui.Image image = await repaintBoundary.toImage(
    pixelRatio: imageSize.width / logicalSize.width,
  );
  final ByteData? byteData =
      await image.toByteData(format: ui.ImageByteFormat.png);

  return byteData?.buffer.asUint8List();
}