从小部件或画布创建原始图像

35

我的最终目标是通过传递原始图像数据或将图像保存到磁盘以供本地Android/iOS服务共享动态图像。如何将 Flutter 中的 WidgetCanvas 转换为原始图像数据(例如 byte[])?

3个回答

45

现在已经支持这个功能了。您可以使用 RenderRepaintBoundaryOffsetLayer 或者 Scene。它们都有一个 toImage 方法。以下是 RenderRepaintBoundary.toImage() 的链接。

class PngHome extends StatefulWidget {
  const PngHome({super.key});

  @override
  PngHomeState createState() => PngHomeState();
}

class PngHomeState extends State<PngHome> {
  GlobalKey globalKey = GlobalKey();

  Future<void> _capturePng() async {
    RenderRepaintBoundary boundary = globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
    ui.Image image = await boundary.toImage();
    ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    Uint8List pngBytes = byteData!.buffer.asUint8List();
    print(pngBytes);
  }

  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      key: globalKey,
      child: Center(
        child: TextButton(
          onPressed: _capturePng,
          child: const Text('Take screenshot', textDirection: TextDirection.ltr),
        ),
      ),
    );
  }
}

这是从文档复制并适应了最新的null safety和dart语言特性。值得注意的是,globalKey.currentContextbyteData 的值可能为空,因此最好在生产代码中对它们进行检查。


2
@colin 如果可能的话,请尝试将您想要捕获的部分包装在提到的小部件之一中。此外,Scene.toImage() 接收宽度和高度,您可以以不同的方式利用它们(我不确定它是否裁剪或扭曲原始图像): - Andrei Tudor Diaconu
2
经历了绘制阶段。这是否意味着小部件必须在屏幕上? - lawonga
1
@lawonga 我认为小部件不需要在屏幕上,因为您还可以指定像素密度来绘制它(不依赖于实际设备密度)。 - Andrei Tudor Diaconu
@AndreiTudorDiaconu - 捕捉小部件的屏幕外部分非常重要,如果您不介意贡献,请在此处打开有关此问题的问题:https://stackoverflow.com/questions/57583965/flutter-dart-capture-entire-partially-offscreen-widget-as-image - A. L. Strine
无法将findRenderObject的结果分配给RenderRepaintBoundary,因为类型不同。“无法将类型为'RenderObject?'的值分配给类型为'RenderRepaintBoundary'的变量。” - JPLauber
显示剩余5条评论

6

5

目前在FlutterView中运行的Dart代码无法实现此功能,但是我们已经跟踪了一个问题以实现这一点:https://github.com/flutter/flutter/issues/6774

可以将Flutter小部件作为FlutterView的一部分渲染,然后使用Java或Objective-C接口到FlutterView来捕获图片,例如标准的android.View.getBitmap,FlutterView实现了该接口:https://docs.flutter.io/javadoc/io/flutter/view/FlutterView.html#getBitmap--

如果您的应用程序需要此功能,并且希望能够从Dart代码内部捕获Widget树的位图,则我们很乐意听取您的意见。请随时提供有关上述问题的更多上下文信息!


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