Browse Source

implemented TolerantImageComparer

af/merge-core
Anton Firszov 9 years ago
parent
commit
c292c75acd
  1. 4
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs
  2. 2
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs
  3. 3
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageSimilarityReport.cs
  4. 60
      tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs

4
tests/ImageSharp.Tests/TestUtilities/ImageComparison/ExactImageComparer.cs

@ -11,7 +11,9 @@ namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
public static ExactImageComparer Instance { get; } = new ExactImageComparer();
public override ImageSimilarityReport CompareImagesOrFrames<TPixelA, TPixelB>(ImageBase<TPixelA> expected, ImageBase<TPixelB> actual)
public override ImageSimilarityReport CompareImagesOrFrames<TPixelA, TPixelB>(
ImageBase<TPixelA> expected,
ImageBase<TPixelB> actual)
{
if (expected.Size() != actual.Size())
{

2
tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs

@ -6,6 +6,8 @@ namespace ImageSharp.Tests.TestUtilities.ImageComparison
using ImageSharp.PixelFormats;
using SixLabors.Primitives;
public abstract class ImageComparer
{
public static ImageComparer Exact { get; } = ExactImageComparer.Instance;

3
tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageSimilarityReport.cs

@ -14,6 +14,9 @@
this.Differences = differences.ToArray();
}
public static ImageSimilarityReport Empty =>
new ImageSimilarityReport(null, null, Enumerable.Empty<PixelDifference>());
public IImageBase ExpectedImage { get; }
public IImageBase ActualImage { get; }

60
tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs

@ -1,6 +1,11 @@
namespace ImageSharp.Tests.TestUtilities.ImageComparison
{
using System;
using System.Collections.Generic;
using ImageSharp.PixelFormats;
using SixLabors.Primitives;
public class TolerantImageComparer : ImageComparer
{
@ -34,7 +39,60 @@
public override ImageSimilarityReport CompareImagesOrFrames<TPixelA, TPixelB>(ImageBase<TPixelA> expected, ImageBase<TPixelB> actual)
{
throw new NotImplementedException();
if (expected.Size() != actual.Size())
{
throw new InvalidOperationException("Calling ImageComparer is invalid when dimensions mismatch!");
}
int width = actual.Width;
// TODO: Comparing through Rgba32 is not robust enough because of the existance of super high precision pixel types.
Rgba32[] aBuffer = new Rgba32[width];
Rgba32[] bBuffer = new Rgba32[width];
double totalDifference = 0.0;
var differences = new List<PixelDifference>();
for (int y = 0; y < actual.Height; y++)
{
Span<TPixelA> aSpan = expected.GetRowSpan(y);
Span<TPixelB> bSpan = actual.GetRowSpan(y);
PixelOperations<TPixelA>.Instance.ToRgba32(aSpan, aBuffer, width);
PixelOperations<TPixelB>.Instance.ToRgba32(bSpan, bBuffer, width);
for (int x = 0; x < width; x++)
{
int d = GetDifferenceInPixelByteSum(ref aBuffer[x], ref bBuffer[x]);
if (d > this.PixelThresholdInPixelByteSum)
{
var diff = new PixelDifference(new Point(x, y), aBuffer[x], bBuffer[x]);
differences.Add(diff);
float percentageDiff = (float)d / 4.0f / 255.0f;
totalDifference += percentageDiff;
}
}
}
if (totalDifference > this.ImageThreshold)
{
return new ImageSimilarityReport(expected, actual, differences);
}
else
{
return ImageSimilarityReport.Empty;
}
}
private static int GetDifferenceInPixelByteSum(ref Rgba32 expected, ref Rgba32 actual)
{
return (int)actual.R - (int)expected.R + (int)actual.G - (int)expected.G + (int)actual.B - (int)expected.B
+ (int)actual.A - (int)expected.A;
}
}
}
Loading…
Cancel
Save