需求
需要將相關(guān)的widget轉(zhuǎn)成圖片。
實(shí)現(xiàn)
通過(guò) RenderRepaintBoundry.toImage()來(lái)獲取Image數(shù)據(jù),pixelRatio
屬性可以調(diào)整圖片的清晰度。
RenderRepaintBoundry.toImage()
內(nèi)部調(diào)用offsetLayer.toImage
方法棚愤;offsetLayer.toImage
調(diào)用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';
實(shí)現(xiàn)代碼
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