|
| 1 | +// Copyright (c) Six Labors. |
| 2 | +// Licensed under the Six Labors Split License. |
| 3 | + |
| 4 | +using SixLabors.ImageSharp; |
| 5 | +using SixLabors.ImageSharp.Memory; |
| 6 | +using SixLabors.ImageSharp.PixelFormats; |
| 7 | + |
| 8 | +namespace SixLabors.Fonts.Tests.ImageComparison; |
| 9 | + |
| 10 | +public class ExactImageComparer : ImageComparer |
| 11 | +{ |
| 12 | + public static ExactImageComparer Instance { get; } = new ExactImageComparer(); |
| 13 | + |
| 14 | + public override ImageSimilarityReport<TPixelA, TPixelB> CompareImagesOrFrames<TPixelA, TPixelB>( |
| 15 | + int index, |
| 16 | + ImageFrame<TPixelA> expected, |
| 17 | + ImageFrame<TPixelB> actual) |
| 18 | + { |
| 19 | + if (expected.Size != actual.Size) |
| 20 | + { |
| 21 | + throw new InvalidOperationException("Calling ImageComparer is invalid when dimensions mismatch!"); |
| 22 | + } |
| 23 | + |
| 24 | + int width = actual.Width; |
| 25 | + |
| 26 | + // TODO: Comparing through Rgba64 may not be robust enough because of the existence of super high precision pixel types. |
| 27 | + Rgba64[] aBuffer = new Rgba64[width]; |
| 28 | + Rgba64[] bBuffer = new Rgba64[width]; |
| 29 | + |
| 30 | + List<PixelDifference> differences = new(); |
| 31 | + Configuration configuration = expected.Configuration; |
| 32 | + Buffer2D<TPixelA> expectedBuffer = expected.PixelBuffer; |
| 33 | + Buffer2D<TPixelB> actualBuffer = actual.PixelBuffer; |
| 34 | + |
| 35 | + for (int y = 0; y < actual.Height; y++) |
| 36 | + { |
| 37 | + Span<TPixelA> aSpan = expectedBuffer.DangerousGetRowSpan(y); |
| 38 | + Span<TPixelB> bSpan = actualBuffer.DangerousGetRowSpan(y); |
| 39 | + |
| 40 | + PixelOperations<TPixelA>.Instance.ToRgba64(configuration, aSpan, aBuffer); |
| 41 | + PixelOperations<TPixelB>.Instance.ToRgba64(configuration, bSpan, bBuffer); |
| 42 | + |
| 43 | + for (int x = 0; x < width; x++) |
| 44 | + { |
| 45 | + Rgba64 aPixel = aBuffer[x]; |
| 46 | + Rgba64 bPixel = bBuffer[x]; |
| 47 | + |
| 48 | + if (aPixel != bPixel) |
| 49 | + { |
| 50 | + PixelDifference diff = new(new Point(x, y), aPixel, bPixel); |
| 51 | + differences.Add(diff); |
| 52 | + } |
| 53 | + } |
| 54 | + } |
| 55 | + |
| 56 | + return new ImageSimilarityReport<TPixelA, TPixelB>(index, expected, actual, differences); |
| 57 | + } |
| 58 | +} |
0 commit comments