自动优化网站建设热线最好用的免费建站平台
flutter开发实战-RepaintBoundary实现Widget截图功能
在开发中,遇到需要使用截图,像iOS可以截图UIView获取到UIImage,在flutter中可以使用RepaintBoundary实现截图功能
相机拍摄的图片:
RepaintBoundary截图后的图片
一、RepaintBoundary
RepaintBoundary是绘制边界。
如果CustomPaint有子节点,为了避免子节点不必要的重绘并提高性能,通常情况下都会将子节点包裹在RepaintBoundary组件中,这样会在绘制时就会创建一个新的绘制层(Layer),其子组件将在新的Layer上绘制,而父组件将在原来Layer上绘制,也就是说RepaintBoundary 子组件的绘制将独立于父组件的绘制,RepaintBoundary会隔离其子节点和CustomPaint本身的绘制边界。示例如下:
CustomPaint(size: Size(300, 300), //指定画布大小painter: MyPainter(),child: RepaintBoundary(child:...)),
)
参考:https://book.flutterchina.club/chapter10/custom_paint.html#_10-4-1-custompaint
二、实现Widget截图
实现Widget截图,需要将Widget嵌套在RepaintBoundary里,需要用到Globalkey
示例如下
Container(width: widget.width,height: widget.height,clipBehavior: Clip.hardEdge,decoration: BoxDecoration(color: Colors.transparent,),child: RepaintBoundary(key: _cameraViewGlobalKey,child: Transform.scale(scale: scale * aspectRatio,child: AspectRatio(aspectRatio: aspectRatio,child: Center(child: CameraPreview(controller!,),),),),),);
实现截图功能
// 根据GlobalKey来截图Widgetstatic Future<Uint8List?> makeImageUInt8List(GlobalKey globalKey) async {RenderRepaintBoundary boundary =globalKey.currentContext?.findRenderObject() as RenderRepaintBoundary;// 这个可以获取当前设备的像素比var dpr = ui.window.devicePixelRatio;ui.Image image = await boundary.toImage(pixelRatio: dpr);ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);Uint8List? pngBytes = byteData?.buffer.asUint8List();return pngBytes;}
获得Uint8List,可以直接将其写入文件或者使用Image展示。
if (uInt8List != null) {await File(imagePath).writeAsBytes(uInt8List);}
三、小结
flutter开发实战-RepaintBoundary实现Widget截图功能,像iOS可以截图UIView获取到UIImage,在flutter中可以使用RepaintBoundary实现截图功能。