如何在Flutter-web中从widget创建图像?

7
要在Google地图上显示自定义小部件,我使用了一个非常方便的功能,将任何Widget(包括包含图片的Widget)转换为Image,然后将其转换为所需的Uint8List。在iOS和Android上表现良好。参考链接:google_maps_flutter
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上使用此函数时,出现了以下错误:

不支持的操作:在Web上不支持toImage

现在Flutter已经支持Image.toByteDataPicture.toImage #20750,但我无法想象这如何在我的情况下使用。

实际上问题是-如何改造此函数以使其在Web上也能工作?

谢谢,我很高兴听取任何想法


1
PR显示已合并到Flutter主通道。您能否切换您的通道并再次测试? - Abhilash Chandran
@AbhilashChandran 我无论如何都在使用主分支。不幸的是,这个PR并没有意味着实现repaintBoundary.toImage。因此,我正在寻找一种不需要repaintBoundary.toImage的解决方案。 - Alex
2个回答

4

如果你在flutter build web的参数中添加--dart-define=FLUTTER_WEB_USE_SKIAtoImage()方法将会生效。

该方法在本地可正常工作,无需添加此参数。

我在查看crop包文档时发现了这个解决方案,该包也使用了toImage()方法。

编辑

通过iPhone访问应用程序时遇到了一些问题,从小部件生成图像有效,但在项目中的某些动画停止工作。

我发现了这个问题,我将使用参数--dart-define=FLUTTER_WEB_AUTO_DETECT=true进行一些测试,以查看是否可以在Flutter Web上正确地在桌面、安卓和iOS上工作。

编辑2

在MacOS上经过一些测试,toImage()方法也正常工作。


它可以运行,但图片无法显示。我只看到[object ProgressEvent]而不是图片。我甚至添加了--web-renderer html - undefined

3

repaintBoundary.toImage 功能依赖于 Scene.toImage。根据问题#42767中的评论,该功能在Web上尚未实现。
该问题当前也被降低了优先级。


谢谢提示!但是在这个PR中没有打算使用repaintBoundary.toImage,也许是Scene.toImage - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接