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

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 namespace SixLabors.ImageSharp.Tests.Drawing
{ {
public class FillPatternBrushTests : FileTestBase public class FillPatternBrushTests
{ {
private void Test(string name, Rgba32 background, IBrush<Rgba32> brush, Rgba32[,] expectedPattern) 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)) using (var image = new Image<Rgba32>(20, 20))
{ {
image.Mutate(x => x.Fill(background).Fill(brush)); 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"); 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> where TPixel : struct, IPixel<TPixel>
{ {
provider.Utility.TestGroupName = this.GetType().Name; provider.Utility.TestGroupName = this.GetType().Name;
var f = (FieldInfo)typeof(Color).GetMember(colorName)[0]; Color color = TestUtils.GetColorByName(colorName);
Color color = (Color)f.GetValue(null);
provider.RunValidatingProcessorTest(x => this.Apply(x, color), colorName, ValidatorComparer, appendPixelTypeToFileName: false); 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> /// <returns>The pixel types</returns>
internal static PixelTypes[] GetAllPixelTypes() => (PixelTypes[])Enum.GetValues(typeof(PixelTypes)); 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) 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> /// <summary>
/// Utility for testing image processor extension methods: /// Utility for testing image processor extension methods:

2
tests/Images/External

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