|
|
|
@ -1,7 +1,13 @@ |
|
|
|
// ReSharper disable InconsistentNaming
|
|
|
|
namespace ImageSharp.Tests |
|
|
|
{ |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Linq; |
|
|
|
|
|
|
|
using ImageSharp.PixelFormats; |
|
|
|
using ImageSharp.Tests.TestUtilities.ImageComparison; |
|
|
|
|
|
|
|
using Moq; |
|
|
|
|
|
|
|
using SixLabors.Primitives; |
|
|
|
|
|
|
|
@ -18,49 +24,91 @@ namespace ImageSharp.Tests |
|
|
|
private ITestOutputHelper Output { get; } |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithTestPatternImages( |
|
|
|
100, |
|
|
|
100, |
|
|
|
PixelTypes.Rgba32, |
|
|
|
PercentageImageComparer.DefaultImageThreshold, |
|
|
|
PercentageImageComparer.DefaultSegmentThreshold, |
|
|
|
PercentageImageComparer.DefaultScaleIntoSize)] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 0, 0, 100)] |
|
|
|
public void PercentageComparer_ApprovesPerfectSimilarity<TPixel>( |
|
|
|
[WithTestPatternImages(100,100,PixelTypes.Rgba32, 0.0001f, 1)] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 0, 0)] |
|
|
|
public void TolerantImageComparer_ApprovesPerfectSimilarity<TPixel>( |
|
|
|
TestImageProvider<TPixel> provider, |
|
|
|
float imageTheshold, |
|
|
|
byte segmentThreshold, |
|
|
|
int scaleIntoSize) |
|
|
|
int pixelThreshold) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> image = provider.GetImage()) |
|
|
|
{ |
|
|
|
using (Image<TPixel> clone = image.Clone()) |
|
|
|
{ |
|
|
|
PercentageImageComparer.VerifySimilarity( |
|
|
|
image, |
|
|
|
clone, |
|
|
|
imageTheshold, |
|
|
|
segmentThreshold, |
|
|
|
scaleIntoSize); |
|
|
|
var comparer = ImageComparer.Tolerant(imageTheshold, pixelThreshold); |
|
|
|
comparer.VerifySimilarity(image, clone); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static void ModifyPixel<TPixel>(Image<TPixel> img, int x, int y, byte value) |
|
|
|
private static void ModifyPixel<TPixel>(ImageBase<TPixel> img, int x, int y, byte perChannelChange) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
TPixel pixel = img[x, y]; |
|
|
|
var rgbaPixel = default(Rgba32); |
|
|
|
pixel.ToRgba32(ref rgbaPixel); |
|
|
|
rgbaPixel.R += value; |
|
|
|
|
|
|
|
if (rgbaPixel.R + perChannelChange <= 255) |
|
|
|
{ |
|
|
|
rgbaPixel.R += perChannelChange; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
rgbaPixel.R -= perChannelChange; |
|
|
|
} |
|
|
|
|
|
|
|
if (rgbaPixel.G + perChannelChange <= 255) |
|
|
|
{ |
|
|
|
rgbaPixel.G += perChannelChange; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
rgbaPixel.G -= perChannelChange; |
|
|
|
} |
|
|
|
|
|
|
|
if (rgbaPixel.B + perChannelChange <= 255) |
|
|
|
{ |
|
|
|
rgbaPixel.B += perChannelChange; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
rgbaPixel.B -= perChannelChange; |
|
|
|
} |
|
|
|
|
|
|
|
if (rgbaPixel.A + perChannelChange <= 255) |
|
|
|
{ |
|
|
|
rgbaPixel.A += perChannelChange; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
rgbaPixel.A -= perChannelChange; |
|
|
|
} |
|
|
|
|
|
|
|
pixel.PackFromRgba32(rgbaPixel); |
|
|
|
img[x, y] = pixel; |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)] |
|
|
|
public void PercentageComparer_ApprovesImperfectSimilarity<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
public void TolerantImageComparer_ApprovesSimilarityBelowTolerance<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> image = provider.GetImage()) |
|
|
|
{ |
|
|
|
using (Image<TPixel> clone = image.Clone()) |
|
|
|
{ |
|
|
|
ModifyPixel(clone, 0, 0, 1); |
|
|
|
|
|
|
|
var comparer = ImageComparer.Tolerant(); |
|
|
|
comparer.VerifySimilarity(image, clone); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)] |
|
|
|
public void TolerantImageComparer_DoesNotApproveSimilarityAboveTolerance<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> image = provider.GetImage()) |
|
|
|
@ -69,7 +117,27 @@ namespace ImageSharp.Tests |
|
|
|
{ |
|
|
|
ModifyPixel(clone, 0, 0, 2); |
|
|
|
|
|
|
|
PercentageImageComparer.VerifySimilarity(image, clone, scaleIntoSize: 100); |
|
|
|
var comparer = ImageComparer.Tolerant(); |
|
|
|
comparer.VerifySimilarity(image, clone); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)] |
|
|
|
public void TolerantImageComparer_TestPerPixelThreshold<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> image = provider.GetImage()) |
|
|
|
{ |
|
|
|
using (Image<TPixel> clone = image.Clone()) |
|
|
|
{ |
|
|
|
ModifyPixel(clone, 0, 0, 10); |
|
|
|
ModifyPixel(clone, 1, 0, 10); |
|
|
|
ModifyPixel(clone, 2, 0, 10); |
|
|
|
|
|
|
|
var comparer = ImageComparer.Tolerant(pixelThresholdInPixelByteSum: 42); |
|
|
|
comparer.VerifySimilarity(image, clone); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -77,7 +145,7 @@ namespace ImageSharp.Tests |
|
|
|
[Theory] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 99, 100)] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 100, 99)] |
|
|
|
public void PercentageComparer_ThrowsOnSizeMismatch<TPixel>(TestImageProvider<TPixel> provider, int w, int h) |
|
|
|
public void VerifySimilarity_ThrowsOnSizeMismatch<TPixel>(TestImageProvider<TPixel> provider, int w, int h) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> image = provider.GetImage()) |
|
|
|
@ -87,32 +155,35 @@ namespace ImageSharp.Tests |
|
|
|
ImageDimensionsMismatchException ex = Assert.ThrowsAny<ImageDimensionsMismatchException>( |
|
|
|
() => |
|
|
|
{ |
|
|
|
PercentageImageComparer.VerifySimilarity(image, clone); |
|
|
|
ImageComparer comparer = Mock.Of<ImageComparer>(); |
|
|
|
comparer.VerifySimilarity(image, clone); |
|
|
|
}); |
|
|
|
this.Output.WriteLine(ex.Message); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)] |
|
|
|
public void PercentageComparer_WhenDifferenceIsTooLarge_Throws<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
[WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32)] |
|
|
|
public void VerifySimilarity_WhenAnImageFrameIsDifferent_Reports<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> image = provider.GetImage()) |
|
|
|
{ |
|
|
|
using (Image<TPixel> clone = image.Clone()) |
|
|
|
{ |
|
|
|
ModifyPixel(clone, 0, 0, 42); |
|
|
|
ModifyPixel(clone, 1, 0, 42); |
|
|
|
ModifyPixel(clone, 2, 0, 42); |
|
|
|
ModifyPixel(clone.Frames[0], 42, 43, 1); |
|
|
|
|
|
|
|
IEnumerable<ImageSimilarityReport> reports = ImageComparer.Exact.CompareImages(image, clone); |
|
|
|
|
|
|
|
Assert.ThrowsAny<ImagesSimilarityException>( |
|
|
|
() => { PercentageImageComparer.VerifySimilarity(image, clone, scaleIntoSize: 100); }); |
|
|
|
PixelDifference difference = reports.Single().Differences.Single(); |
|
|
|
Assert.Equal(new Point(42, 43), difference.Position); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)] |
|
|
|
public void ExactComparer_ApprovesExactEquality<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
@ -122,34 +193,14 @@ namespace ImageSharp.Tests |
|
|
|
{ |
|
|
|
using (Image<TPixel> clone = image.Clone()) |
|
|
|
{ |
|
|
|
ExactImageComparer.Instance.Verify(image, clone); |
|
|
|
ExactImageComparer.Instance.CompareImages(image, clone); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 99, 100)] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32, 100, 99)] |
|
|
|
public void ExactComparer_ThrowsOnSizeMismatch<TPixel>(TestImageProvider<TPixel> provider, int w, int h) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> image = provider.GetImage()) |
|
|
|
{ |
|
|
|
using (Image<TPixel> clone = image.Clone(ctx => ctx.Resize(w, h))) |
|
|
|
{ |
|
|
|
ImageDimensionsMismatchException ex = Assert.ThrowsAny<ImageDimensionsMismatchException>( |
|
|
|
() => |
|
|
|
{ |
|
|
|
ExactImageComparer.Instance.Verify(image, clone); |
|
|
|
}); |
|
|
|
this.Output.WriteLine(ex.Message); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Theory] |
|
|
|
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)] |
|
|
|
public void ExactComparer_ThrowsOnSmallestPixelDifference<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
public void ExactComparer_DoesNotTolerateAnyPixelDifference<TPixel>(TestImageProvider<TPixel> provider) |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
using (Image<TPixel> image = provider.GetImage()) |
|
|
|
@ -159,15 +210,13 @@ namespace ImageSharp.Tests |
|
|
|
ModifyPixel(clone, 42, 24, 1); |
|
|
|
ModifyPixel(clone, 7, 93, 1); |
|
|
|
|
|
|
|
ImagesAreNotEqualException ex = Assert.ThrowsAny<ImagesAreNotEqualException>( |
|
|
|
() => |
|
|
|
{ |
|
|
|
ExactImageComparer.Instance.Verify(image, clone); |
|
|
|
}); |
|
|
|
this.Output.WriteLine(ex.Message); |
|
|
|
Assert.Equal(2, ex.Differences.Length); |
|
|
|
Assert.Contains(new Point(42, 24), ex.Differences); |
|
|
|
Assert.Contains(new Point(7, 93), ex.Differences); |
|
|
|
IEnumerable<ImageSimilarityReport> reports = ExactImageComparer.Instance.CompareImages(image, clone); |
|
|
|
|
|
|
|
this.Output.WriteLine(reports.Single().ToString()); |
|
|
|
PixelDifference[] differences = reports.Single().Differences; |
|
|
|
Assert.Equal(2, differences.Length); |
|
|
|
Assert.Contains(differences, d => d.Position == new Point(42, 24)); |
|
|
|
Assert.Contains(differences, d => d.Position == new Point(7, 93)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|