dart - RenderRepaintBoundary 到图像而不将小部件添加到屏幕

标签 dart flutter

我正在尝试从小部件导出图像而不将此小部件添加到屏幕。
这甚至可能吗?
我已经通过添加到可滚动容器成功导出它,现在我想渲染它而不将其添加到屏幕并将其保存到临时文件以供共享。
我认为那里应该有一个“油漆”电话,但无法弄清楚确切的位置。

这是我的代码:

var shareImage = await ShareImageWidget.builder(context,
item: item, definition: definition);
var widget = shareImage.build(context);
var repaint = RepaintBoundary.wrap(widget, 0);
var render = RenderRepaintBoundary(child:repaint.createRenderObject(context));
ui.Image image = await render.toImage(pixelRatio: 1.0);
ByteData byteData = await image.toByteData(format:ui.ImageByteFormat.png);
var pngBytes = byteData.buffer.asUint8List();
var bs64 = base64Encode(pngBytes);
var dir = await getTemporaryDirectory();

最佳答案

例子:

/// 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();
}

引用:https://github.com/flutter/flutter/issues/40064#issuecomment-620081426
有一个具有此功能的软件包:https://pub.dev/packages/screenshot#capturing-widgets-that-are-not-in-the-widget-tree

关于dart - RenderRepaintBoundary 到图像而不将小部件添加到屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55134343/

相关文章:

unit-testing - 单元测试失败,断言失败 : line 17: '<optimized out>' : is not true

flutter - flutter 随机化-如何防止显示先前显示的元素

android - 如何从 GridView 中删除内部滚动条?

Dart、try.dart 使用 Mixins 时出错

android - 如何防止抖动中的 Image.file() 滞后?

使用 fromJson flutter null 安全性

flutter - 我应该使用//或///在 Dart 中进行评论吗?它会使应用程序变慢吗?

flutter - 向 Flutter 应用程序添加启动画面

flutter - 如何在Flutter中将图像和其他 View 用作背景

json - 当json是数组列表时,如何将json转换为dart?