58 lines
1.8 KiB
Dart
58 lines
1.8 KiB
Dart
|
|
import 'dart:typed_data';
|
||
|
|
import 'dart:ui' as ui;
|
||
|
|
|
||
|
|
import 'package:flutter/material.dart';
|
||
|
|
import 'package:flutter/rendering.dart';
|
||
|
|
|
||
|
|
Future<Uint8List?> createImageFromWidget(BuildContext context, Widget widget, {Duration? wait, Size? logicalSize, Size? imageSize}) async {
|
||
|
|
final repaintBoundary = RenderRepaintBoundary();
|
||
|
|
|
||
|
|
logicalSize ??= View.of(context).physicalSize / View.of(context).devicePixelRatio;
|
||
|
|
imageSize ??= View.of(context).physicalSize;
|
||
|
|
|
||
|
|
assert(logicalSize.aspectRatio == imageSize.aspectRatio, 'logicalSize and imageSize must not be the same');
|
||
|
|
|
||
|
|
final renderView = RenderView(
|
||
|
|
child: RenderPositionedBox(alignment: Alignment.center, child: repaintBoundary),
|
||
|
|
configuration: ViewConfiguration(
|
||
|
|
physicalConstraints: BoxConstraints.tight(logicalSize),
|
||
|
|
logicalConstraints: BoxConstraints.tight(logicalSize),
|
||
|
|
devicePixelRatio: 1,
|
||
|
|
),
|
||
|
|
view: View.of(context) //PlatformDispatcher.instance.views.first,
|
||
|
|
);
|
||
|
|
|
||
|
|
final pipelineOwner = PipelineOwner();
|
||
|
|
final buildOwner = BuildOwner(focusManager: FocusManager());
|
||
|
|
|
||
|
|
pipelineOwner.rootNode = renderView;
|
||
|
|
renderView.prepareInitialFrame();
|
||
|
|
|
||
|
|
final rootElement = RenderObjectToWidgetAdapter<RenderBox>(
|
||
|
|
container: repaintBoundary,
|
||
|
|
child: Directionality(
|
||
|
|
textDirection: TextDirection.ltr,
|
||
|
|
child: widget,
|
||
|
|
)).attachToRenderTree(buildOwner);
|
||
|
|
|
||
|
|
buildOwner.buildScope(rootElement);
|
||
|
|
|
||
|
|
if (wait != null) {
|
||
|
|
await Future.delayed(wait);
|
||
|
|
}
|
||
|
|
|
||
|
|
buildOwner
|
||
|
|
..buildScope(rootElement)
|
||
|
|
..finalizeTree();
|
||
|
|
|
||
|
|
pipelineOwner
|
||
|
|
..flushLayout()
|
||
|
|
..flushCompositingBits()
|
||
|
|
..flushPaint();
|
||
|
|
|
||
|
|
final image = await repaintBoundary.toImage(pixelRatio: imageSize.width / logicalSize.width);
|
||
|
|
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
|
||
|
|
|
||
|
|
return byteData?.buffer.asUint8List();
|
||
|
|
}
|