Flutter 将小部件直接保存到图像中

Bul*_*dru 6 mobile dart flutter

我有一个自定义小部件,我想将其保存为 png 图像。我面临的问题是,在当前的实现中,我需要在屏幕上显示小部件。我想要的是将小部件直接保存到图像中而不显示它。

作为解决方法,我会在图像在屏幕上呈现时第一时间保存图像,然后快速将其关闭。

这就是我现在保存小部件的方式:


class SomeWidget extends StatefulWidget {
  const SomeWidget({
    Key key,
  }) : super(key: key);

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

class _SomeWidgetState extends State<SomeWidget>
    with AfterLayoutMixin<SomeWidget> {
  GlobalKey globalKey = GlobalKey();

  Future<void> _capturePng() async {
    RenderRepaintBoundary boundary =
        globalKey.currentContext.findRenderObject();
    try {
      if (boundary.debugNeedsPaint) {
        print("Waiting for boundary to be painted.");
        await Future.delayed(const Duration(milliseconds: 5));
        return _capturePng();
      }
    } catch (_) {}
    try {
      ui.Image image = await boundary.toImage();
      ByteData byteData =
          await image.toByteData(format: ui.ImageByteFormat.png);
      Uint8List pngBytes = byteData.buffer.asUint8List();

      // SHARING IMAGE TO SOCIAL MEDIA
      // CODE

      // widget is presented with a dialog so I just pop it
      Navigator.of(context).pop();
    } catch (_) {
      await Future.delayed(const Duration(milliseconds: 5));
      return _capturePng();
    }
  }

  @override
  void afterFirstLayout(BuildContext context) {
    _capturePng();
  }

  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      key: globalKey,
      child: SuperFancyWidget(),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

afterFirstLayout 来自https://pub.dev/packages/after_layout

gre*_*bra 5

屏幕截图包 ( https://pub.dev/packages/screenshot ) 已更新,现在支持捕获未显示在屏幕上的小部件。

所以像下面这样的东西应该有效:

ScreenshotController screenshotController = ScreenshotController();
  late File customFile;
Run Code Online (Sandbox Code Playgroud)
await screenshotController
              .captureFromWidget(CustomWidget())
              .then((capturedImage) async {
            await widgetToImageFile(capturedImage);
Run Code Online (Sandbox Code Playgroud)
  Future<void> widgetToImageFile(
    Uint8List capturedImage,
  ) async {
    Directory tempDir = await getTemporaryDirectory();
    String tempPath = tempDir.path;
    final ts = DateTime.now().millisecondsSinceEpoch.toString();
    String path = '$tempPath/$ts.png';
    customFile = await File(path).writeAsBytes(capturedImage);
  }
Run Code Online (Sandbox Code Playgroud)

现在您应该有一个包含您的小部件的 .png 的自定义文件,可以根据需要进行处理。


Nii*_*iLx 3

好吧,如果你想将你的小部件保存为 png 图片,你可以使用截图包。像这样包装小部件:

Screenshot(
    controller: screenshotController,
    child: Text("This text will be captured as image"),
)
Run Code Online (Sandbox Code Playgroud)

请阅读自述文件部分以了解包中的详细信息。

  • 您提到的包完全符合我在实现中所做的事情。我正在寻找一种解决方案来保存图像中的屏幕小部件。但据我所知,目前这是不可能的。 (2认同)