如何从 Flutter-web 中的小部件创建图像?

Posted

技术标签:

【中文标题】如何从 Flutter-web 中的小部件创建图像?【英文标题】:How to create an image from a widget in Flutter-web? 【发布时间】:2021-01-15 19:16:34 【问题描述】:

为了在谷歌地图google_maps_flutter 上显示自定义小部件,我使用了一个非常方便的函数,它将任何Widget(包括那些包含图像的)转换为Image,然后我将其转换为我需要的Uint8List。它在 iosandroid 上运行良好。

Future createImageFromWidget( Widget widget)
  final RenderRepaintBoundary repaintBoundary = RenderRepaintBoundary();
  final RenderView renderView = RenderView(
    child: RenderPositionedBox(alignment: Alignment.center, child: repaintBoundary),
    configuration: ViewConfiguration(size: const Size.square(300.0), devicePixelRatio: ui.window.devicePixelRatio),
    window: null,
  );

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

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

  buildOwner..buildScope(rootElement)..finalizeTree();
  pipelineOwner..flushLayout()..flushCompositingBits()..flushPaint();

  return repaintBoundary.toImage(pixelRatio: ui.window.devicePixelRatio)
    .then((image) => image.toByteData(format: ui.ImageByteFormat.png))
    .then((byteData) => byteData.buffer.asUint8List());

但不幸的是,当我尝试在 Web 上使用此功能时,我收到以下错误:

不支持的操作:网络上不支持toImage

现在 Flutter 支持 Image.toByteDataPicture.toImage #20750,但我不知道如何在我的情况下使用它。

实际上的问题是 - 如何重新制作这个函数,以便它也可以在 Web 上运行?

谢谢你,我会很高兴有任何想法

【问题讨论】:

PR 显示已合并到 Flutter 主频道。你能换个频道再测试一下吗? @AbhilashChandran 无论如何我都在使用主分支。不幸的是,这个 PR 并不意味着 repaintBoundary.toImage 的实现。因此,我正在寻找一种无需repaintBoundary.toImage 的解决方案。 【参考方案1】:

如果您将--dart-define=FLUTTER_WEB_USE_SKIA 放在flutter build web 参数上,则

toImage() 有效。

该方法在没有此参数的情况下在本地工作。

我在看到crop 包文档后找到了这个解决方案,它也使用了 toImage()

编辑

我在通过 iPhone 访问应用程序时发现了一些问题,从小部件生成图像工作正常,但我在项目中的一些动画停止工作。

我找到了这个question,我将只使用参数--dart-define=FLUTTER_WEB_AUTO_DETECT=true 进行一些测试,以查看Flutter web 在桌面、Android 和iOS 上是否正常工作。

编辑 2

在 MacO 上进行了一些测试,toImage() 方法也可以正常工作。

【讨论】:

【参考方案2】:

repaintBoundary.toImage 功能依赖于 Scene.toImage,根据问题 #42767 中的 cmets 尚未为 Web 实现。 该问题目前也没有被优先考虑。

【讨论】:

感谢您的提示!但在此 PR 中,无意将 repaintBoundary.toImage 设为 Scene.toImage

以上是关于如何从 Flutter-web 中的小部件创建图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何从stackedLayout访问centralWidget中的小部件?

Qt 如何从 QVector 中的数据创建位图并将其显示在小部件上?

如何在不影响 Pyqt5 中的小部件的情况下将背景图像添加到主窗口

pyqt - 如何从状态栏中的小部件中删除边框?

如何在带有背景图像的小部件上制作隐形按钮?

如何从python中的小部件在任何窗口上绘制