compareUiImages function

Future<MyComparisonResult> compareUiImages(
  1. Image testImage,
  2. Image masterImage
)

Implementation

Future<MyComparisonResult> compareUiImages(
    Image testImage, Image masterImage) async {
  final ByteData? testImageRgba = await testImage.toByteData();
  final ByteData? masterImageRgba = await masterImage.toByteData();

  final int width = testImage.width;
  final int height = testImage.height;

  if (width != masterImage.width || height != masterImage.height) {
    return MyComparisonResult(
      passed: false,
      diffPercent: 1.0,
      pixelDiffHistogram: null, // NOTE MODIFIED ADD
      error: 'Pixel test failed, image sizes do not match.\n'
          'Master Image: ${masterImage.width} X ${masterImage.height}\n'
          'Test Image: ${testImage.width} X ${testImage.height}',
    );
  }

  int pixelDiffCount = 0;
  final int totalPixels = width * height;
  final pixelDiffHistogram =
      SimpleHistogram(totalSampleCount: totalPixels); // NOTE MODIFIED ADD
  final ByteData invertedMasterRgba = _invert(masterImageRgba!);
  final ByteData invertedTestRgba = _invert(testImageRgba!);

  final Uint8List testImageBytes =
      (await testImage.toByteData())!.buffer.asUint8List();
  final ByteData maskedDiffRgba = ByteData(testImageBytes.length);
  maskedDiffRgba.buffer
      .asUint8List()
      .setRange(0, testImageBytes.length, testImageBytes);
  final ByteData isolatedDiffRgba = ByteData(width * height * 4);

  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      final int byteOffset = (width * y + x) * 4;
      final int testPixel = testImageRgba.getUint32(byteOffset);
      final int masterPixel = masterImageRgba.getUint32(byteOffset);

      final int diffPixel =
          (_readRed(testPixel) - _readRed(masterPixel)).abs() +
              (_readGreen(testPixel) - _readGreen(masterPixel)).abs() +
              (_readBlue(testPixel) - _readBlue(masterPixel)).abs() +
              (_readAlpha(testPixel) - _readAlpha(masterPixel)).abs();

      if (diffPixel != 0) {
        final int invertedMasterPixel =
            invertedMasterRgba.getUint32(byteOffset);
        final int invertedTestPixel = invertedTestRgba.getUint32(byteOffset);
        // We grab the max of the 0xAABBGGRR encoded bytes, and then convert
        // back to 0xRRGGBBAA for the actual pixel value, since this is how it
        // was historically done.
        final int maskPixel = _toRGBA(max(
          _toABGR(invertedMasterPixel),
          _toABGR(invertedTestPixel),
        ));
        maskedDiffRgba.setUint32(byteOffset, maskPixel);
        isolatedDiffRgba.setUint32(byteOffset, maskPixel);
        pixelDiffCount++;
        pixelDiffHistogram.addSample(diffPixel); // NOTE MODIFIED ADD
      }
    }
  }

  if (pixelDiffCount > 0) {
    final double diffPercent = pixelDiffCount / totalPixels;
    return MyComparisonResult(
      passed: false,
      diffPercent: diffPercent,
      pixelDiffHistogram: pixelDiffHistogram,
      error: 'Pixel test failed, '
          '${(diffPercent * 100).toStringAsFixed(2)}% '
          'diff detected.',
      diffs: <String, Image>{
        'masterImage': masterImage,
        'testImage': testImage,
        'maskedDiff': await _createImage(maskedDiffRgba, width, height),
        'isolatedDiff': await _createImage(isolatedDiffRgba, width, height),
      },
    );
  }
  return MyComparisonResult(
    passed: true,
    diffPercent: 0.0,
    pixelDiffHistogram: null, // NOTE MODIFIED ADD
  );
}