Creating raw image from Widget or Canvas

There is support for this now. You can either use RenderRepaintBoundry or OffsetLayer or Scene. They all have a toImage. Here is the link to RenderRepaintBoundry.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),
        ),
      ),
    );
  }
}

This is copied from the docs and adapted to latest null safety and dart language features. The values for globalKey.currentContext and byteData can be null, so your production code should ideally check them.

Leave a Comment