Browse Source

validating tests for: DrawPath, FillComplexPolygon

af/merge-core
Anton Firszov 7 years ago
parent
commit
5c571f5d9f
  1. 133
      tests/ImageSharp.Tests/Drawing/DrawPathTests.cs
  2. 62
      tests/ImageSharp.Tests/Drawing/FillComplexPolygonTests.cs
  3. 6
      tests/ImageSharp.Tests/Drawing/FillPatternBrushTests.cs
  4. 109
      tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs
  5. 3
      tests/ImageSharp.Tests/Processing/Processors/Overlays/OverlayTestBase.cs
  6. 9
      tests/ImageSharp.Tests/TestUtilities/TestUtils.cs
  7. 2
      tests/Images/External

133
tests/ImageSharp.Tests/Drawing/DrawPathTests.cs

@ -1,112 +1,79 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.Primitives;
using SixLabors.Shapes;
using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
public class DrawPathTests : FileTestBase
[GroupOutput("Drawing")]
public class DrawPathTests
{
[Fact]
public void ImageShouldBeOverlayedByPath()
public static readonly TheoryData<string, byte, float> DrawPathData = new TheoryData<string, byte, float>
{
{ "White", 255, 1.5f },
{ "Red", 255, 3 },
{ "HotPink", 255, 5 },
{ "HotPink", 150, 5 },
{ "White", 255, 15 },
};
[Theory]
[WithSolidFilledImages(nameof(DrawPathData), 300, 450, "Blue", PixelTypes.Rgba32)]
public void DrawPath<TPixel>(TestImageProvider<TPixel> provider, string colorName, byte alpha, float thickness)
where TPixel : struct, IPixel<TPixel>
{
string path = TestEnvironment.CreateOutputDirectory("Drawing", "Path");
using (var image = new Image<Rgba32>(500, 500))
{
var linerSegemnt = new LinearLineSegment(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var bazierSegment = new CubicBezierLineSegment(
new Vector2(50, 300),
new Vector2(500, 500),
new Vector2(60, 10),
new Vector2(10, 400));
var p = new Path(linerSegemnt, bazierSegment);
image.Mutate(x => x.BackgroundColor(Rgba32.Blue));
image.Mutate(x => x.Draw(Rgba32.HotPink, 5, p));
image.Save($"{path}/Simple.png");
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
}
[Fact]
public void ImageShouldBeOverlayedPathWithOpacity()
{
string path = TestEnvironment.CreateOutputDirectory("Drawing", "Path");
var color = new Rgba32(Rgba32.HotPink.R, Rgba32.HotPink.G, Rgba32.HotPink.B, 150);
var linerSegemnt = new LinearLineSegment(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
);
var bazierSegment = new CubicBezierLineSegment(new Vector2(50, 300),
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var bazierSegment = new CubicBezierLineSegment(
new Vector2(50, 300),
new Vector2(500, 500),
new Vector2(60, 10),
new Vector2(10, 400));
var p = new Path(linerSegemnt, bazierSegment);
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x.BackgroundColor(Rgba32.Blue));
image.Mutate(x => x.Draw(color, 10, p));
image.Save($"{path}/Opacity.png");
var path = new Path(linerSegemnt, bazierSegment);
//shift background color towards forground color by the opacity amount
var mergedColor = new Rgba32(
Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
Rgba32 rgba = TestUtils.GetColorByName(colorName);
rgba.A = alpha;
Color color = rgba;
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(mergedColor, sourcePixels[11, 11]);
FormattableString testDetails = $"{colorName}_A{alpha}_T{thickness}";
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
provider.RunValidatingProcessorTest(
x => x.Draw(color.ToPixel<TPixel>(), thickness, path),
testDetails,
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
}
[Fact]
public void PathExtendingOffEdgeOfImageShouldNotBeCropped()
[Theory]
[WithSolidFilledImages(256, 256, "Black", PixelTypes.Rgba32)]
public void PathExtendingOffEdgeOfImageShouldNotBeCropped<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
string path = TestEnvironment.CreateOutputDirectory("Drawing", "Path");
using (var image = new Image<Rgba32>(256, 256))
{
image.Mutate(x => x.Fill(Rgba32.Black));
Pen<Rgba32> pen = Pens.Solid(Rgba32.White, 5f);
for (int i = 0; i < 300; i += 20)
{
image.Mutate(
x => x.DrawLines(
pen,
new SixLabors.Primitives.PointF[] { new Vector2(100, 2), new Vector2(-10, i) }));
}
image.Save($"{path}/ClippedLines.png");
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.White, sourcePixels[0, 90]);
}
Color color = Color.White;
Pen<TPixel> pen = Pens.Solid(color.ToPixel<TPixel>(), 5f);
provider.RunValidatingProcessorTest(
x =>
{
for (int i = 0; i < 300; i += 20)
{
PointF[] points = new PointF[] { new Vector2(100, 2), new Vector2(-10, i) };
x.DrawLines(pen, points);
}
},
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
}
}
}

62
tests/ImageSharp.Tests/Drawing/FillComplexPolygonTests.cs

@ -0,0 +1,62 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.Shapes;
using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
[GroupOutput("Drawing")]
public class FillComplexPolygonTests
{
[Theory]
[WithSolidFilledImages(300, 400, "Blue", PixelTypes.Rgba32, false, false)]
[WithSolidFilledImages(300, 400, "Blue", PixelTypes.Rgba32, true, false)]
[WithSolidFilledImages(300, 400, "Blue", PixelTypes.Rgba32, false, true)]
public void ComplexPolygon_SolidFill<TPixel>(TestImageProvider<TPixel> provider, bool overlap, bool transparent)
where TPixel :struct, IPixel<TPixel>
{
var simplePath = new Polygon(new LinearLineSegment(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)));
var hole1 = new Polygon(new LinearLineSegment(
new Vector2(37, 85),
overlap ? new Vector2(130, 40) : new Vector2(93, 85),
new Vector2(65, 137)));
IPath clipped = simplePath.Clip(hole1);
Rgba32 colorRgba = Rgba32.HotPink;
if (transparent)
{
colorRgba.A = 150;
}
Color color = colorRgba;
string testDetails = "";
if (overlap)
{
testDetails += "_Overlap";
}
if (transparent)
{
testDetails += "_Transparent";
}
provider.RunValidatingProcessorTest(
x => x.Fill(color.ToPixel<TPixel>(), clipped),
testDetails,
appendPixelTypeToFileName: false,
appendSourceFileOrDescription: false);
}
}
}

6
tests/ImageSharp.Tests/Drawing/FillPatternTests.cs → tests/ImageSharp.Tests/Drawing/FillPatternBrushTests.cs

@ -12,11 +12,11 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
public class FillPatternBrushTests : FileTestBase
public class FillPatternBrushTests
{
private void Test(string name, Rgba32 background, IBrush<Rgba32> brush, Rgba32[,] expectedPattern)
{
string path = TestEnvironment.CreateOutputDirectory("Fill", "PatternBrush");
string path = TestEnvironment.CreateOutputDirectory("Drawing", "FillPatternBrushTests");
using (var image = new Image<Rgba32>(20, 20))
{
image.Mutate(x => x.Fill(background).Fill(brush));
@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
}
}
image.Mutate(x => x.Resize(80, 80));
image.Mutate(x => x.Resize(80, 80, KnownResamplers.NearestNeighbor));
image.Save($"{path}/{name}x4.png");
}
}

109
tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs

@ -1,109 +0,0 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.Shapes;
using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
public class SolidComplexPolygonTests : FileTestBase
{
[Fact]
public void ImageShouldBeOverlayedByPolygonOutline()
{
string path = TestEnvironment.CreateOutputDirectory("Drawing", "ComplexPolygon");
var simplePath = new Polygon(new LinearLineSegment(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)));
var hole1 = new Polygon(new LinearLineSegment(
new Vector2(37, 85),
new Vector2(93, 85),
new Vector2(65, 137)));
IPath clipped = simplePath.Clip(hole1);
// var clipped = new Rectangle(10, 10, 100, 100).Clip(new Rectangle(20, 0, 20, 20));
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x.BackgroundColor(Rgba32.Blue));
image.Mutate(x => x.Fill(Rgba32.HotPink, clipped));
image.Save($"{path}/Simple.png");
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[20, 35]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[60, 100]);
}
}
[Fact]
public void ImageShouldBeOverlayedPolygonOutlineWithOverlap()
{
string path = TestEnvironment.CreateOutputDirectory("Drawing", "ComplexPolygon");
var simplePath = new Polygon(new LinearLineSegment(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)));
var hole1 = new Polygon(new LinearLineSegment(
new Vector2(37, 85),
new Vector2(130, 40),
new Vector2(65, 137)));
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x.BackgroundColor(Rgba32.Blue));
image.Mutate(x => x.Fill(Rgba32.HotPink, simplePath.Clip(hole1)));
image.Save($"{path}/SimpleOverlapping.png");
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[20, 35]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[60, 100]);
}
}
[Fact]
public void ImageShouldBeOverlayedPolygonOutlineWithOpacity()
{
string path = TestEnvironment.CreateOutputDirectory("Drawing", "ComplexPolygon");
var simplePath = new Polygon(new LinearLineSegment(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)));
var hole1 = new Polygon(new LinearLineSegment(
new Vector2(37, 85),
new Vector2(93, 85),
new Vector2(65, 137)));
var color = new Rgba32(Rgba32.HotPink.R, Rgba32.HotPink.G, Rgba32.HotPink.B, 150);
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x.BackgroundColor(Rgba32.Blue));
image.Mutate(x => x.Fill(color, simplePath.Clip(hole1)));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
var mergedColor = new Rgba32(
Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(mergedColor, sourcePixels[20, 35]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[60, 100]);
}
}
}
}

3
tests/ImageSharp.Tests/Processing/Processors/Overlays/OverlayTestBase.cs

@ -27,8 +27,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Overlays
where TPixel : struct, IPixel<TPixel>
{
provider.Utility.TestGroupName = this.GetType().Name;
var f = (FieldInfo)typeof(Color).GetMember(colorName)[0];
Color color = (Color)f.GetValue(null);
Color color = TestUtils.GetColorByName(colorName);
provider.RunValidatingProcessorTest(x => this.Apply(x, color), colorName, ValidatorComparer, appendPixelTypeToFileName: false);
}

9
tests/ImageSharp.Tests/TestUtilities/TestUtils.cs

@ -141,8 +141,15 @@ namespace SixLabors.ImageSharp.Tests
/// <returns>The pixel types</returns>
internal static PixelTypes[] GetAllPixelTypes() => (PixelTypes[])Enum.GetValues(typeof(PixelTypes));
internal static Color GetColorByName(string colorName)
{
var f = (FieldInfo)typeof(Color).GetMember(colorName)[0];
return (Color)f.GetValue(null);
}
internal static TPixel GetPixelOfNamedColor<TPixel>(string colorName)
where TPixel : struct, IPixel<TPixel> => (TPixel)typeof(NamedColors<TPixel>).GetTypeInfo().GetField(colorName).GetValue(null);
where TPixel : struct, IPixel<TPixel> =>
GetColorByName(colorName).ToPixel<TPixel>();
/// <summary>
/// Utility for testing image processor extension methods:

2
tests/Images/External

@ -1 +1 @@
Subproject commit c057090b4402120a83a8efe251aa5b691db9c0dc
Subproject commit d83843deedc43712f29f631aab090640b4f54946
Loading…
Cancel
Save