美文网首页
flutter widget to image

flutter widget to image

作者: gooddaytoyou | 来源:发表于2022-01-21 18:05 被阅读0次
    需求

    需要将相关的widget转成图片。

    实现

    通过 RenderRepaintBoundry.toImage()来获取Image数据,pixelRatio属性可以调整图片的清晰度。

    RenderRepaintBoundry.toImage() 内部调用offsetLayer.toImage方法;offsetLayer.toImage调用scene.toImage方法,交给底层处理。

    Future<ui.Image> toImage({ double pixelRatio = 1.0 }) {
      assert(!debugNeedsPaint);
      final OffsetLayer offsetLayer = layer! as OffsetLayer;
      return offsetLayer.toImage(Offset.zero & size, pixelRatio: pixelRatio);
    }
    ...
    Future<ui.Image> toImage(Rect bounds, { double pixelRatio = 1.0 }) async {
       ....
        try {
          // Size is rounded up to the next pixel to make sure we don't clip off
          // anything.
          return await scene.toImage(
            (pixelRatio * bounds.width).ceil(),
            (pixelRatio * bounds.height).ceil(),
          );
        } finally {
          scene.dispose();
        }
      }
    }
    
    ...
       String? _toImage(int width, int height, _Callback<_Image?> callback) native 'Scene_toImage';
    

    实现代码

    class _MyHomePageState extends State<MyHomePage> {
      final GlobalKey genKey = GlobalKey();
    
      String? imagePath;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                const Text(
                  'Create an Image from Widget',
                ),
                RepaintBoundary(
                  key: genKey,
                  child: const ListTile(
                    leading: CircleAvatar(),
                    title: Text("Hello,friend"),
                  ),
                ),
                if (imagePath != null) Image.file(File(imagePath!))
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _takePicture,
            tooltip: 'start',
            child: const Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    
      Future<void> _takePicture() async {
        RenderRepaintBoundary? boundary =
            genKey.currentContext?.findRenderObject() as RenderRepaintBoundary?;
    
        ui.Image? image = await boundary?.toImage(pixelRatio: 5);
        ByteData? byteData =
            await image?.toByteData(format: ui.ImageByteFormat.png);
    
        final directory = (await getApplicationDocumentsDirectory()).path;
        File? imgFile = File('$directory/photo.png');
    
        Uint8List? pngBytes = byteData?.buffer.asUint8List();
        imgFile.writeAsBytes(pngBytes!);
        setState(() {
          imagePath = imgFile.path;
        });
      }
    

    源码

    https://github.com/sayhellotogithub/flutter-widget-to-image

    参考

    https://medium.com/flutter-community/export-your-widget-to-image-with-flutter-dc7ecfa6bafb

    https://api.flutter.dev/flutter/rendering/RenderRepaintBoundary/toImage.html

    https://stackoverflow.com/questions/41957086/creating-raw-image-from-widget-or-canvas

    https://guoshuyu.cn/home/wx/Flutter-21.html

    相关文章

      网友评论

          本文标题:flutter widget to image

          本文链接:https://www.haomeiwen.com/subject/svzehrtx.html