computeDimension function

QrDimension? computeDimension({
  1. required Position<double> topLeft,
  2. required Position<double> topRight,
  3. required Position<double> bottomLeft,
  4. required BitMatrix matrix,
})

Computes the size of finder patterns along multiple directions vertical and horizontal directions, assuming that each finder pattern can be recognized in any direction as a sequence of 5 alternating black and white modules.

Implementation

QrDimension? computeDimension({
  required final Position<double> topLeft,
  required final Position<double> topRight,
  required final Position<double> bottomLeft,
  required final BitMatrix matrix,
}) {
  final topLeftVertical = countBlackWhiteRun(
    origin: topLeft,
    end: bottomLeft,
    matrix: matrix,
    length: 5,
  ).reduce((a, b) => a + b);

  final topLeftHorizontal = countBlackWhiteRun(
    origin: topLeft,
    end: topRight,
    matrix: matrix,
    length: 5,
  ).reduce((a, b) => a + b);

  final bottomLeftVertical = countBlackWhiteRun(
    origin: bottomLeft,
    end: topLeft,
    matrix: matrix,
    length: 5,
  ).reduce((a, b) => a + b);

  final topRightHorizontal = countBlackWhiteRun(
    origin: topRight,
    end: topLeft,
    matrix: matrix,
    length: 5,
  ).reduce((a, b) => a + b);

  // Make sure the measures make sense (each measure must be at least 7,
  // given that a finder pattern is 7 x 7 modules)
  if (topLeftVertical < 7 ||
      topLeftHorizontal < 7 ||
      bottomLeftVertical < 7 ||
      topRightHorizontal < 7) {
    return null;
  }

  // Find the module dimension from the average of the finder pattern sizes
  final double module = (topLeftVertical +
          topLeftHorizontal +
          bottomLeftVertical +
          topRightHorizontal) /
      4 /
      7;

  final topSize = (topLeft.distanceTo(topRight) / module).round();
  final sideSize = (topLeft.distanceTo(bottomLeft) / module).round();
  int size = ((topSize + sideSize) / 2).floor() + 7;
  switch (size % 4) {
    case 0:
      size++;
      break;
    case 2:
      size--;
      break;
  }
  return QrDimension(size: size, module: module);
}