Flutter如何实现截图画图分享

截图

  1. 用RepaintBoundary包裹要截图的Widget
  2. 给RepaintBoundary设置一个GlobalKey, 如名字: _globalKey
  3. 计算floatPixelRatio应该是多少(如果计算有误, 会导致截取后的图在放大缩小过程中出现线条不柔和, 比如水平直线每隔一段会有1px的错位, 显得直线忽上忽下)
    计算方式:
设计图的宽度/屏幕的宽度 * 要拼接的是几倍的设计图

设计图的宽度/屏幕的宽度 * 要拼接的是几倍的设计图
比如我们设计图给的是360*640, 屏幕实际宽度是375pt, 当前要截取的图待会要和3倍的资源图片组合成一张图(画图过程用到), 那么就应该这么算

floatPixelRatio = 360 / 375 * 3 = 2.88
  1. 通过下面代码获取要截取的ui.Image, 完成截图
RenderRepaintBoundary boundary =
        _globalKey.currentContext.findRenderObject();
    ui.Image centerImage = await boundary.toImage(pixelRatio: floatPixelRatio);

画图

画图API流程

Created with Raphaël 2.2.0 创建PictureRecorder 传递到Canvas 通过Canvas画图 通过PictureRecorder获取Picture 从Picture中读取ui.Image

代码逻辑如下:

    /// start draw
    final recorder = new PictureRecorder();
    final canvas = new Canvas(recorder,
        new Rect.fromPoints(new Offset(0, 0), new Offset(width, height)));
    /// 顶部的图片
    canvas.drawImageRect...
    /// 文字
    TextPainter labelTp = new TextPainter...
    labelTp.paint(canvas...
    /// end draw
    final picture = recorder.endRecording();
    ui.Image finalUiImage =
        await picture.toImage(width.toInt(), height.toInt());

值得注意的是, 如果想要文字居中需要自己计算文字的宽高:

    TextPainter labelTp = new TextPainter(
        text: labelSpan,
        textAlign: TextAlign.left,
        textDirection: TextDirection.ltr);
    labelTp.layout();
    double secHeight = labelTp.height;
    double secondLength = labelTp.width;

分享

分享图片比较简单, 获取上述产生的ui.Image保存到文件夹中, 调用fluwx分享该文件即可
保存文件方法:


  Future _shareUiImage(ui.Image uiImage) async {
    /// 分享图片
    ByteData finalByteData =
        await uiImage.toByteData(format: ImageByteFormat.png);
    Uint8List finalPngBytes = finalByteData.buffer.asUint8List();

    String appDocPath = await DirectoryUtil.getTempDirectory();
    final imageFile = File(path.join(appDocPath, 'dart.png')); // 保存在应用文件夹内
    logger.d("appDocPath= " +
        appDocPath +
        " imageFile= " +
        imageFile.path.toString());
    await imageFile.writeAsBytes(finalPngBytes); 

    return imageFile;
  }

DirectoryUtil.getTempDirectory()这个方法是使用path_provider on pub实现的
使用fluwx分享文件可以参考fluwx on github

你可能感兴趣的:(flutter)