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;
}
}
}
}
}