generateImageFromWidget static method
Future<ImageElement?>
generateImageFromWidget(
- BuildContext context,
- Widget widget, [
- ImageElement? imageElement
Captures a widget-frame that is not build in a widget tree. Inspired by screenshot plugin
Implementation
static Future<ImageElement?> generateImageFromWidget(wid.BuildContext context, wid.Widget widget, [ImageElement? imageElement]) async {
try {
/// boundary widget by GlobalKey
rend.RenderRepaintBoundary? boundary = rend.RenderRepaintBoundary();
final flutterView = wid.View.of(context);
final pixelRatio = flutterView.devicePixelRatio;
wid.Size logicalSize = flutterView.physicalSize / pixelRatio;
wid.Size imageSize = flutterView.physicalSize;
assert(logicalSize.aspectRatio.toStringAsPrecision(5) == imageSize.aspectRatio.toStringAsPrecision(5));
final rend.RenderView renderView = rend.RenderView(
view: flutterView,
child: rend.RenderPositionedBox(alignment: wid.Alignment.center, child: boundary),
configuration: rend.ViewConfiguration(
physicalConstraints: rend.BoxConstraints.tight(logicalSize) * pixelRatio,
logicalConstraints: rend.BoxConstraints.tight(logicalSize),
devicePixelRatio: pixelRatio,
),
);
final rend.PipelineOwner pipelineOwner = rend.PipelineOwner();
final wid.BuildOwner buildOwner = wid.BuildOwner(focusManager: wid.FocusManager(), onBuildScheduled: () {});
pipelineOwner.rootNode = renderView;
renderView.prepareInitialFrame();
final wid.RenderObjectToWidgetElement<rend.RenderBox> rootElement =
wid.RenderObjectToWidgetAdapter<rend.RenderBox>(
container: boundary,
child: wid.Directionality(
textDirection: wid.TextDirection.ltr,
child: widget,
)
).attachToRenderTree(
buildOwner,
);
buildOwner.buildScope(
rootElement,
);
buildOwner.finalizeTree();
pipelineOwner.flushLayout();
pipelineOwner.flushCompositingBits();
pipelineOwner.flushPaint();
/// convert boundary to image
final image = await boundary.toImageSync(pixelRatio: pixelRatio);
final data = (await image.toByteData(format: ui.ImageByteFormat.rawRgba))?.buffer.asUint8List();
if(data == null){
return null;
}
else if(imageElement != null){
imageElement.width = image.width;
imageElement.height = image.height;
if(imageElement.data == null){
imageElement.data = Uint8Array.fromList(data);
}
else{
(imageElement.data as Uint8Array).set(data);
}
return imageElement;
}
return ImageElement(
width: image.width,
height: image.height,
data: Uint8Array.fromList(data)
);
} catch (e) {
rethrow;
}
}