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来截图Widget
  static 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实现截图功能。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐