是否可以将隐藏的小部件导出为图像?

问题描述 投票:0回答:2

我知道如何使用

RepaintBoundary

将可见小部件保存到图像中

我想要的是一种将用户不可见的

widget
保存为
image
的方法。

android flutter dart flutter-layout
2个回答
0
投票
/// Creates an image from the given widget by first spinning up a element and render tree,
/// then waiting for the given [wait] amount of time and then creating an image via a [RepaintBoundary].
/// 
/// The final image will be of size [imageSize] and the the widget will be layout, ... with the given [logicalSize].
Future<Uint8List> createImageFromWidget(Widget widget, {Duration wait, Size logicalSize, Size imageSize}) async {
  final RenderRepaintBoundary repaintBoundary = RenderRepaintBoundary();

  logicalSize ??= ui.window.physicalSize / ui.window.devicePixelRatio;
  imageSize ??= ui.window.physicalSize;

  assert(logicalSize.aspectRatio == imageSize.aspectRatio);

  final RenderView renderView = RenderView(
    window: null,
    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: widget,
  ).attachToRenderTree(buildOwner);

  buildOwner.buildScope(rootElement);

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

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

  pipelineOwner.flushLayout();
  pipelineOwner.flushCompositingBits();
  pipelineOwner.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();
}

了解更多


0
投票

您可以使用此代码创建不可见的小部件图像。 `

 static 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(
      size: 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: ImageByteFormat.png);

return byteData?.buffer.asUint8List();
}`

欲了解更多参考,您可以访问此链接

© www.soinside.com 2019 - 2024. All rights reserved.