flutter widget to image

需求

需要將相關的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

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容