我正试着快速地在屏幕上画出很多点.我创建了以下方法.

void _paintPoints(Canvas canvas, List matrix, Size size) {
  final width = size.width / matrix.length;
  final height = size.height / matrix.first.length;
  Float32List points = Float32List(matrix.length * matrix.length * 2);
  final pointColors = <Color>[];

  for (var i = 0; i < matrix.length; i++) {
    for (var j = 0; j < matrix[i].length; j++) {
      final x = i * width;
      final y = j * height;
      final index = (i * matrix.length + j) * 2;

      points[index] = x;
      points[index + 1] = y;

      Color color = Color.fromARGB(
          matrix[i][j][3], matrix[i][j][0], matrix[i][j][1], matrix[i][j][2]);
      pointColors.add(color);
    }
  }

  canvas.drawRawPoints(
    PointMode.points,
    points,
    paint
      ..blendMode = BlendMode.srcOver
      ..strokeWidth = 2.0,
  );
}

这种方法能够快速绘制点,但所有的点都是相同的 colored颜色 (不使用pointColors).有没有办法用drawRawPoints()或其他Canvas方法用特定的 colored颜色 快速画出很多点(几万个)?

我试着把每个点分开画,但太慢了.

推荐答案

你能试试这个吗?

void _paintPoints(Canvas canvas, List matrix, Size size) {
  final width = size.width / matrix.length;
  final height = size.height / matrix.first.length;

  final Map<Color, Set<Offset>> map = HashMap();

  for (var i = 0; i < matrix.length; i++) {
    for (var j = 0; j < matrix[i].length; j++) {
      final offset = Offset(i * width, j * height);
      final color = Color.fromARGB(
          matrix[i][j][3], matrix[i][j][0], matrix[i][j][1], matrix[i][j][2]);
      map.putIfAbsent(color, () => HashSet()).add(offset);
    }
  }

  for (var e in map.entries) {
    canvas.drawRawPoints(
      PointMode.points,
      Float32List.fromList(e.value.expand((e) => [e.dx, e.dy]).toList()),
      paint
        ..color = e.key
        ..blendMode = BlendMode.srcOver
        ..strokeWidth = 2.0,
    );
  }
}

很抱歉,我不得不把它作为回复贴出来.这是一个试用代码.我建议缓存映射结果,并使用即将到来的矩阵和大小的比较来计算新的映射值.

编辑: 我做了一些编辑,它应该运行得很快.这里的 idea 是最大限度地减少内存地址计算.

更新的代码

void _paintPoints(Canvas canvas, List matrix, Size size) {
  final r = matrix.length;
  final c = matrix.first.length;
  final width = size.width / r;
  final height = size.height / c;

  final Map<Color, Set<Offset>> map = HashMap();

  for (var i = 0; i < r; i++) {
    final row = matrix[i];
    for (var j = 0; j < c; j++) {
      final cell = row[j];
      final offset = Offset(i * width, j * height);
      final color = Color.fromARGB(cell[3], cell[0], cell[1], cell[2]);
      map.putIfAbsent(color, () => HashSet()).add(offset);
    }
  }

  for (var e in map.entries) {
    canvas.drawPoints(
      PointMode.points,
      e.value.toList(),
      paint
        ..color = e.key
        ..blendMode = BlendMode.srcOver
        ..strokeWidth = 2.0,
    );
  }
}

现在 map 的创建速度应该要快得多.我自己做了一些基准测试,发现用i和j访问3D列表比引用它要花更多的时间.此外,还将行点更改为点.你可以把它改回来.

Flutter相关问答推荐

Firebase Auth异常未被catch捕获

如何在凌晨12点显示00:00(24小时格式)而不是在Flutter 中显示24:00

有没有什么方法可以加快在Flutter 中加载Quill HTML编辑器的速度?

轻松本地化包翻译在底部导航栏项目标签Flutter 翼dart 中不起作用

如何翻转这种剪刀设计

不要跨同步间隔使用BuildContext

Ffltter Firebase向用户添加公司

使用现有Map方法对子类克隆方法的逻辑进行Dart标准化

hooks_riverpod 有用途吗

如何使用Riverpod提供程序正确构建搜索栏?

无法将Null类型的值分配给 const 构造函数中List类型的参数

更改下拉按钮的背景 colored颜色 - flutter

如何将此文本按钮剪辑在堆栈中的圆形头像上方?

如何在 Flutter 中测试动画图标

从子类调用超类的超方法

在提供程序包更改通知程序中构建倒计时时钟

应用程序和应用程序内的 webview 之间的单点登录

在 Flutter 中,您什么时候应该更喜欢Widget继承而不是组合?

我收到这个错误我无法解决

未处理的异常:FileSystemException:无法打开文件,路径 = 'assets/res.zip'(操作系统错误:没有这样的文件或目录,errno = 2)