namespace ImageSharp.Tests { using System; using ImageSharp; using Xunit; /// /// Class to perform simple image comparisons. /// public static class ImageComparer { const int DefaultScalingFactor = 32; const int DefaultSegmentThreshold = 3; const float DefaultImageThreshold = 0.000f; public static void VisualComparer(Image expected, Image actual, float imageTheshold = DefaultImageThreshold, byte segmentThreshold = DefaultSegmentThreshold, int scalingFactor = DefaultScalingFactor) where TColorA : struct, IPixel where TColorB : struct, IPixel { float percentage = expected.PercentageDifference(actual, segmentThreshold, scalingFactor); Assert.InRange(percentage, 0, imageTheshold); } public static float PercentageDifference(this Image source, Image target, byte segmentThreshold = DefaultSegmentThreshold, int scalingFactor = DefaultScalingFactor) where TColorA : struct, IPixel where TColorB : struct, IPixel { // code adapted from https://www.codeproject.com/Articles/374386/Simple-image-comparison-in-NET Fast2DArray differences = GetDifferences(source, target, scalingFactor); int diffPixels = 0; foreach (byte b in differences.Data) { if (b > segmentThreshold) { diffPixels++; } } return diffPixels / (scalingFactor * scalingFactor); } private static Fast2DArray GetDifferences(Image source, Image target, int scalingFactor) where TColorA : struct, IPixel where TColorB : struct, IPixel { Fast2DArray differences = new Fast2DArray(scalingFactor, scalingFactor); Fast2DArray firstGray = source.GetGrayScaleValues(scalingFactor); Fast2DArray secondGray = target.GetGrayScaleValues(scalingFactor); for (int y = 0; y < scalingFactor; y++) { for (int x = 0; x < scalingFactor; x++) { differences[x, y] = (byte)Math.Abs(firstGray[x, y] - secondGray[x, y]); } } return differences; } private static Fast2DArray GetGrayScaleValues(this Image source, int scalingFactor) where TColorA : struct, IPixel { byte[] buffer = new byte[4]; using (Image img = new Image(source).Resize(scalingFactor, scalingFactor).Grayscale()) { using (PixelAccessor pixels = img.Lock()) { Fast2DArray grayScale = new Fast2DArray(scalingFactor, scalingFactor); for (int y = 0; y < scalingFactor; y++) { for (int x = 0; x < scalingFactor; x++) { pixels[x, y].ToXyzBytes(buffer, 0); grayScale[x, y] = buffer[1]; } } return grayScale; } } } } }