Browse Source

Add basic comparision tests

af/merge-core
James Jackson-South 8 years ago
parent
commit
99225bc589
  1. 2
      src/ImageSharp/PixelFormats/PixelBlenderMode.cs
  2. 2
      src/ImageSharp/PixelFormats/PixelOperations{TPixel}.PixelBenders.cs
  3. 2
      tests/ImageSharp.Tests/Drawing/DrawImageTest.cs
  4. 52
      tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffCompositorTests.cs
  5. 4
      tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs
  6. 88
      tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.Blender.cs
  7. 2
      tests/ImageSharp.Tests/TestImages.cs
  8. 3
      tests/Images/Input/Png/pd-dest.png
  9. 3
      tests/Images/Input/Png/pd-source.png

2
src/ImageSharp/PixelFormats/PixelBlenderMode.cs

@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <summary>
/// Blends the 2 values by subtraction.
/// </summary>
Substract,
Subtract,
/// <summary>
/// Multiplies the complements of the backdrop and source values, then complements the result.

2
src/ImageSharp/PixelFormats/PixelOperations{TPixel}.PixelBenders.cs

@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
case PixelBlenderMode.Multiply: return DefaultPixelBlenders<TPixel>.Multiply.Instance;
case PixelBlenderMode.Add: return DefaultPixelBlenders<TPixel>.Add.Instance;
case PixelBlenderMode.Substract: return DefaultPixelBlenders<TPixel>.Substract.Instance;
case PixelBlenderMode.Subtract: return DefaultPixelBlenders<TPixel>.Subtract.Instance;
case PixelBlenderMode.Screen: return DefaultPixelBlenders<TPixel>.Screen.Instance;
case PixelBlenderMode.Darken: return DefaultPixelBlenders<TPixel>.Darken.Instance;
case PixelBlenderMode.Lighten: return DefaultPixelBlenders<TPixel>.Lighten.Instance;

2
tests/ImageSharp.Tests/Drawing/DrawImageTest.cs

@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Tests
[WithFileCollection(nameof(TestFiles), PixelTypes, PixelBlenderMode.Normal)]
[WithFileCollection(nameof(TestFiles), PixelTypes, PixelBlenderMode.Multiply)]
[WithFileCollection(nameof(TestFiles), PixelTypes, PixelBlenderMode.Add)]
[WithFileCollection(nameof(TestFiles), PixelTypes, PixelBlenderMode.Substract)]
[WithFileCollection(nameof(TestFiles), PixelTypes, PixelBlenderMode.Subtract)]
[WithFileCollection(nameof(TestFiles), PixelTypes, PixelBlenderMode.Screen)]
[WithFileCollection(nameof(TestFiles), PixelTypes, PixelBlenderMode.Darken)]
[WithFileCollection(nameof(TestFiles), PixelTypes, PixelBlenderMode.Lighten)]

52
tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffCompositorTests.cs

@ -0,0 +1,52 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Drawing;
using Xunit;
namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders
{
public class PorterDuffCompositorTests
{
// TODO: Add other modes to compare.
private static PixelBlenderMode[] CompositingOperators =
{
PixelBlenderMode.Src,
PixelBlenderMode.Atop,
PixelBlenderMode.Over,
PixelBlenderMode.In,
PixelBlenderMode.Out,
PixelBlenderMode.Dest,
PixelBlenderMode.DestAtop,
PixelBlenderMode.DestOver,
PixelBlenderMode.DestIn,
PixelBlenderMode.DestOut,
PixelBlenderMode.Clear,
PixelBlenderMode.Xor
};
[Fact]
public void PorterDuffOutputIsCorrect()
{
string path = TestEnvironment.CreateOutputDirectory("PorterDuff");
var srcFile = TestFile.Create(TestImages.Png.PDSrc);
var destFile = TestFile.Create(TestImages.Png.PDDest);
using (Image<Rgba32> src = srcFile.CreateImage())
using (Image<Rgba32> dest = destFile.CreateImage())
{
foreach (PixelBlenderMode m in CompositingOperators)
{
using (Image<Rgba32> res = dest.Clone(x => x.Blend(src, new GraphicsOptions { BlenderMode = m })))
{
// TODO: Generate reference files once this works.
res.Save($"{path}/{m}.png");
}
}
}
}
}
}

4
tests/ImageSharp.Tests/PixelFormats/PixelBlenders/PorterDuffFunctionsTests_TPixel.cs

@ -160,7 +160,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders
public void SubstractFunction_Blender<TPixel>(TestPixel<TPixel> back, TestPixel<TPixel> source, float amount, TestPixel<TPixel> expected)
where TPixel : struct, IPixel<TPixel>
{
TPixel actual = new DefaultPixelBlenders<TPixel>.Substract().Blend(back, source, amount);
TPixel actual = new DefaultPixelBlenders<TPixel>.Subtract().Blend(back, source, amount);
VectorAssert.Equal(expected, actual, 2);
}
@ -170,7 +170,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders
where TPixel : struct, IPixel<TPixel>
{
Span<TPixel> dest = new Span<TPixel>(new TPixel[1]);
new DefaultPixelBlenders<TPixel>.Substract().Blend(this.MemoryManager, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount));
new DefaultPixelBlenders<TPixel>.Subtract().Blend(this.MemoryManager, dest, back.AsSpan(), source.AsSpan(), AsSpan(amount));
VectorAssert.Equal(expected, dest[0], 2);
}

88
tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.Blender.cs

@ -16,53 +16,53 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
public static TheoryData<object, Type, PixelBlenderMode> BlenderMappings = new TheoryData<object, Type, PixelBlenderMode>()
{
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Normal), PixelBlenderMode.Normal },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Screen), PixelBlenderMode.Screen },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.HardLight), PixelBlenderMode.HardLight },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Overlay), PixelBlenderMode.Overlay },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Darken), PixelBlenderMode.Darken },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Lighten), PixelBlenderMode.Lighten },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Add), PixelBlenderMode.Add },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Substract), PixelBlenderMode.Substract },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Multiply), PixelBlenderMode.Multiply },
{
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Normal), PixelBlenderMode.Normal },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Screen), PixelBlenderMode.Screen },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.HardLight), PixelBlenderMode.HardLight },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Overlay), PixelBlenderMode.Overlay },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Darken), PixelBlenderMode.Darken },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Lighten), PixelBlenderMode.Lighten },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Add), PixelBlenderMode.Add },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Subtract), PixelBlenderMode.Subtract },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Multiply), PixelBlenderMode.Multiply },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Src), PixelBlenderMode.Src },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Atop), PixelBlenderMode.Atop },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Over), PixelBlenderMode.Over },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.In), PixelBlenderMode.In },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Out), PixelBlenderMode.Out },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Dest), PixelBlenderMode.Dest },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.DestAtop), PixelBlenderMode.DestAtop },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.DestOver), PixelBlenderMode.DestOver },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.DestIn), PixelBlenderMode.DestIn },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.DestOut), PixelBlenderMode.DestOut },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Clear), PixelBlenderMode.Clear },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Xor), PixelBlenderMode.Xor },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Src), PixelBlenderMode.Src },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Atop), PixelBlenderMode.Atop },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Over), PixelBlenderMode.Over },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.In), PixelBlenderMode.In },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Out), PixelBlenderMode.Out },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Dest), PixelBlenderMode.Dest },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.DestAtop), PixelBlenderMode.DestAtop },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.DestOver), PixelBlenderMode.DestOver },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.DestIn), PixelBlenderMode.DestIn },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.DestOut), PixelBlenderMode.DestOut },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Clear), PixelBlenderMode.Clear },
{ new TestPixel<Rgba32>(), typeof(DefaultPixelBlenders<Rgba32>.Xor), PixelBlenderMode.Xor },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Normal), PixelBlenderMode.Normal },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Screen), PixelBlenderMode.Screen },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.HardLight), PixelBlenderMode.HardLight },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Overlay), PixelBlenderMode.Overlay },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Darken), PixelBlenderMode.Darken },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Lighten), PixelBlenderMode.Lighten },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Add), PixelBlenderMode.Add },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Substract), PixelBlenderMode.Substract },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Multiply), PixelBlenderMode.Multiply },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Src), PixelBlenderMode.Src },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Atop), PixelBlenderMode.Atop },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Over), PixelBlenderMode.Over },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.In), PixelBlenderMode.In },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Out), PixelBlenderMode.Out },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Dest), PixelBlenderMode.Dest },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.DestAtop), PixelBlenderMode.DestAtop },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.DestOver), PixelBlenderMode.DestOver },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.DestIn), PixelBlenderMode.DestIn },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.DestOut), PixelBlenderMode.DestOut },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Clear), PixelBlenderMode.Clear },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Xor), PixelBlenderMode.Xor },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Normal), PixelBlenderMode.Normal },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Screen), PixelBlenderMode.Screen },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.HardLight), PixelBlenderMode.HardLight },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Overlay), PixelBlenderMode.Overlay },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Darken), PixelBlenderMode.Darken },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Lighten), PixelBlenderMode.Lighten },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Add), PixelBlenderMode.Add },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Subtract), PixelBlenderMode.Subtract },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Multiply), PixelBlenderMode.Multiply },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Src), PixelBlenderMode.Src },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Atop), PixelBlenderMode.Atop },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Over), PixelBlenderMode.Over },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.In), PixelBlenderMode.In },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Out), PixelBlenderMode.Out },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Dest), PixelBlenderMode.Dest },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.DestAtop), PixelBlenderMode.DestAtop },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.DestOver), PixelBlenderMode.DestOver },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.DestIn), PixelBlenderMode.DestIn },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.DestOut), PixelBlenderMode.DestOut },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Clear), PixelBlenderMode.Clear },
{ new TestPixel<RgbaVector>(), typeof(DefaultPixelBlenders<RgbaVector>.Xor), PixelBlenderMode.Xor },
};
};
[Theory]
[MemberData(nameof(BlenderMappings))]

2
tests/ImageSharp.Tests/TestImages.cs

@ -36,6 +36,8 @@ namespace SixLabors.ImageSharp.Tests
public const string SnakeGame = "Png/SnakeGame.png";
public const string Icon = "Png/icon.png";
public const string Kaboom = "Png/kaboom.png";
public const string PDSrc = "Png/pd-source.png";
public const string PDDest = "Png/pd-dest.png";
// Filtered test images from http://www.schaik.com/pngsuite/pngsuite_fil_png.html
public const string Filter0 = "Png/filter0.png";

3
tests/Images/Input/Png/pd-dest.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:adb9f4448b7bb44d7b4c0ad8c2f3f71b17acb05148375663c7a203707f08660d
size 2563

3
tests/Images/Input/Png/pd-source.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dbf4a45b89eddeb727e0437846bcef5d875f532f94aaa441c75c8c3ddbac5150
size 2393
Loading…
Cancel
Save