Browse Source

#542: refactor tests to follow the recommended pattern for drawing tests, as @antonfirsov suggested.

af/merge-core
Peter Amrehn 8 years ago
parent
commit
d2db63492a
  1. 156
      tests/ImageSharp.Tests/Drawing/FillEllipticGradientBrushTest.cs
  2. 358
      tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs
  3. 84
      tests/ImageSharp.Tests/Drawing/FillRadialGradientBrushTests.cs

156
tests/ImageSharp.Tests/Drawing/FillEllipticGradientBrushTest.cs

@ -12,113 +12,135 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing namespace SixLabors.ImageSharp.Tests.Drawing
{ {
[GroupOutput("Drawing/GradientBrushes")]
public class FillEllipticGradientBrushTests : FileTestBase public class FillEllipticGradientBrushTests : FileTestBase
{ {
[Fact] [Theory]
public void EllipticGradientBrushWithEqualColorsAndReturnsUnicolorImage() [WithBlankImages(10, 10, PixelTypes.Rgba32)]
public void EllipticGradientBrushWithEqualColorsAndReturnsUnicolorImage<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{ {
string path = TestEnvironment.CreateOutputDirectory("Fill", "EllipticGradientBrush"); TPixel red = NamedColors<TPixel>.Red;
using (var image = new Image<Rgba32>(10, 10))
using (Image<TPixel> image = provider.GetImage())
{ {
EllipticGradientBrush<Rgba32> unicolorLinearGradientBrush = EllipticGradientBrush<TPixel> unicolorLinearGradientBrush =
new EllipticGradientBrush<Rgba32>( new EllipticGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0), new SixLabors.Primitives.Point(0, 0),
new SixLabors.Primitives.Point(10, 0), new SixLabors.Primitives.Point(10, 0),
1.0f, 1.0f,
GradientRepetitionMode.None, GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red), new ColorStop<TPixel>(0, red),
new ColorStop<Rgba32>(1, Rgba32.Red)); new ColorStop<TPixel>(1, red));
image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/UnicolorCircleGradient.png"); image.DebugSave(provider);
using (PixelAccessor<Rgba32> sourcePixels = image.Lock()) using (PixelAccessor<TPixel> sourcePixels = image.Lock())
{ {
Assert.Equal(Rgba32.Red, sourcePixels[0, 0]); Assert.Equal(red, sourcePixels[0, 0]);
Assert.Equal(Rgba32.Red, sourcePixels[9, 9]); Assert.Equal(red, sourcePixels[9, 9]);
Assert.Equal(Rgba32.Red, sourcePixels[5, 5]); Assert.Equal(red, sourcePixels[5, 5]);
Assert.Equal(Rgba32.Red, sourcePixels[3, 8]); Assert.Equal(red, sourcePixels[3, 8]);
} }
image.CompareToReferenceOutput(provider);
} }
} }
[Theory] [Theory]
[InlineData(0.1)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1)]
[InlineData(0.4)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4)]
[InlineData(0.8)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8)]
[InlineData(1.0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0)]
[InlineData(1.2)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.2)]
[InlineData(1.6)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.6)]
[InlineData(2.0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 2.0)]
public void EllipticGradientBrushProducesAxisParallelEllipsesWithDifferentRatio( public void EllipticGradientBrushProducesAxisParallelEllipsesWithDifferentRatio<TPixel>(
TestImageProvider<TPixel> provider,
float ratio) float ratio)
where TPixel : struct, IPixel<TPixel>
{ {
string path = TestEnvironment.CreateOutputDirectory("Fill", "EllipticGradientBrush"); TPixel yellow = NamedColors<TPixel>.Yellow;
using (var image = new Image<Rgba32>(1000, 1000)) TPixel red = NamedColors<TPixel>.Red;
TPixel black = NamedColors<TPixel>.Black;
using (var image = provider.GetImage())
{ {
EllipticGradientBrush<Rgba32> unicolorLinearGradientBrush = EllipticGradientBrush<TPixel> unicolorLinearGradientBrush =
new EllipticGradientBrush<Rgba32>( new EllipticGradientBrush<TPixel>(
new SixLabors.Primitives.Point(500, 500), new SixLabors.Primitives.Point(image.Width / 2, image.Height / 2),
new SixLabors.Primitives.Point(500, 750), new SixLabors.Primitives.Point(image.Width / 2, (image.Width * 3) / 2),
ratio, ratio,
GradientRepetitionMode.None, GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Yellow), new ColorStop<TPixel>(0, yellow),
new ColorStop<Rgba32>(1, Rgba32.Red), new ColorStop<TPixel>(1, red),
new ColorStop<Rgba32>(1, Rgba32.Black)); new ColorStop<TPixel>(1, black));
image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/Ellipsis{ratio}.png"); image.DebugSave(provider, ratio);
image.CompareToReferenceOutput(provider, ratio);
} }
} }
[Theory] [Theory]
[InlineData(0.1, 0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 0)]
[InlineData(0.4, 0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 0)]
[InlineData(0.8, 0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 0)]
[InlineData(1.0, 0)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 0)]
[InlineData(0.1, 45)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 45)]
[InlineData(0.4, 45)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 45)]
[InlineData(0.8, 45)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 45)]
[InlineData(1.0, 45)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 45)]
[InlineData(0.1, 90)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 90)]
[InlineData(0.4, 90)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 90)]
[InlineData(0.8, 90)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 90)]
[InlineData(1.0, 90)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 90)]
[InlineData(0.1, 30)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 30)]
[InlineData(0.4, 30)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 30)]
[InlineData(0.8, 30)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 30)]
[InlineData(1.0, 30)] [WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 30)]
public void EllipticGradientBrushProducesRotatedEllipsesWithDifferentRatio( public void EllipticGradientBrushProducesRotatedEllipsesWithDifferentRatio<TPixel>(
TestImageProvider<TPixel> provider,
float ratio, float ratio,
float rotationInDegree) float rotationInDegree)
where TPixel: struct, IPixel<TPixel>
{ {
var center = new SixLabors.Primitives.Point(500, 500); string variant = $"{ratio}at{rotationInDegree}°";
using (var image = provider.GetImage())
{
TPixel yellow = NamedColors<TPixel>.Yellow;
TPixel red = NamedColors<TPixel>.Red;
TPixel black = NamedColors<TPixel>.Black;
var rotation = (Math.PI * rotationInDegree) / 180.0; var center = new SixLabors.Primitives.Point(image.Width / 2, image.Height / 2);
var cos = Math.Cos(rotation);
var sin = Math.Sin(rotation);
int axisX = (int)((center.X * cos) - (center.Y * sin)); var rotation = (Math.PI * rotationInDegree) / 180.0;
int axisY = (int)((center.X * sin) + (center.Y * cos)); var cos = Math.Cos(rotation);
var sin = Math.Sin(rotation);
string path = TestEnvironment.CreateOutputDirectory("Fill", "EllipticGradientBrush"); int axisX = (int)((center.X * cos) - (center.Y * sin));
using (var image = new Image<Rgba32>(1000, 1000)) int axisY = (int)((center.X * sin) + (center.Y * cos));
{
EllipticGradientBrush<Rgba32> unicolorLinearGradientBrush =
new EllipticGradientBrush<Rgba32>( EllipticGradientBrush<TPixel> unicolorLinearGradientBrush =
new EllipticGradientBrush<TPixel>(
center, center,
new SixLabors.Primitives.Point(axisX, axisY), new SixLabors.Primitives.Point(axisX, axisY),
ratio, ratio,
GradientRepetitionMode.None, GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Yellow), new ColorStop<TPixel>(0, yellow),
new ColorStop<Rgba32>(1, Rgba32.Red), new ColorStop<TPixel>(1, red),
new ColorStop<Rgba32>(1, Rgba32.Black)); new ColorStop<TPixel>(1, black));
image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/Ellipsis{ratio}_rot{rotationInDegree}°.png"); image.DebugSave(provider, variant);
image.CompareToReferenceOutput(provider, variant);
} }
} }
} }

358
tests/ImageSharp.Tests/Drawing/FillLinearGradientBrushTests.cs

@ -1,7 +1,10 @@
// 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.Globalization;
using System.Linq; using System.Linq;
using System.Text;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing;
@ -12,305 +15,364 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing namespace SixLabors.ImageSharp.Tests.Drawing
{ {
[GroupOutput("Drawing/GradientBrushes")]
public class FillLinearGradientBrushTests : FileTestBase public class FillLinearGradientBrushTests : FileTestBase
{ {
[Fact] [Theory]
public void LinearGradientBrushWithEqualColorsReturnsUnicolorImage() [WithBlankImages(10, 10, PixelTypes.Rgba32)]
public void WithEqualColorsReturnsUnicolorImage<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{ {
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush"); TPixel red = NamedColors<TPixel>.Red;
using (var image = new Image<Rgba32>(10, 10)) using (var image = provider.GetImage())
{ {
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush = LinearGradientBrush<TPixel> unicolorLinearGradientBrush =
new LinearGradientBrush<Rgba32>( new LinearGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0), new SixLabors.Primitives.Point(0, 0),
new SixLabors.Primitives.Point(10, 0), new SixLabors.Primitives.Point(10, 0),
GradientRepetitionMode.None, GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red), new ColorStop<TPixel>(0, red),
new ColorStop<Rgba32>(1, Rgba32.Red)); new ColorStop<TPixel>(1, red));
image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/UnicolorGradient.png"); image.DebugSave(provider);
image.CompareToReferenceOutput(provider);
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.Red, sourcePixels[0, 0]);
Assert.Equal(Rgba32.Red, sourcePixels[9, 9]);
Assert.Equal(Rgba32.Red, sourcePixels[5, 5]);
Assert.Equal(Rgba32.Red, sourcePixels[3, 8]);
}
} }
} }
[Fact] [Theory]
public void HorizontalLinearGradientBrushReturnsUnicolorColumns() [WithBlankImages(500, 10, PixelTypes.Rgba32)]
public void HorizontalReturnsUnicolorColumns<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{ {
int width = 500; using (var image = provider.GetImage())
int height = 10;
int lastColumnIndex = width - 1;
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush");
using (var image = new Image<Rgba32>(width, height))
{ {
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush = int lastColumnIndex = image.Width - 1;
new LinearGradientBrush<Rgba32>( TPixel red = NamedColors<TPixel>.Red;
TPixel yellow = NamedColors<TPixel>.Yellow;
LinearGradientBrush<TPixel> unicolorLinearGradientBrush =
new LinearGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0), new SixLabors.Primitives.Point(0, 0),
new SixLabors.Primitives.Point(500, 0), new SixLabors.Primitives.Point(image.Width, 0),
GradientRepetitionMode.None, GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red), new ColorStop<TPixel>(0, red),
new ColorStop<Rgba32>(1, Rgba32.Yellow)); new ColorStop<TPixel>(1, yellow));
image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/horizontalRedToYellow.png"); image.DebugSave(provider);
using (PixelAccessor<Rgba32> sourcePixels = image.Lock()) using (PixelAccessor<TPixel> sourcePixels = image.Lock())
{ {
Rgba32 columnColor0 = sourcePixels[0, 0]; TPixel columnColor0 = sourcePixels[0, 0];
Rgba32 columnColor23 = sourcePixels[23, 0]; TPixel columnColor23 = sourcePixels[23, 0];
Rgba32 columnColor42 = sourcePixels[42, 0]; TPixel columnColor42 = sourcePixels[42, 0];
Rgba32 columnColor333 = sourcePixels[333, 0]; TPixel columnColor333 = sourcePixels[333, 0];
Rgba32 lastColumnColor = sourcePixels[lastColumnIndex, 0]; TPixel lastColumnColor = sourcePixels[lastColumnIndex, 0];
for (int i = 0; i < height; i++) for (int i = 0; i < image.Height; i++)
{ {
// check first and last column: // check first and last column:
Assert.Equal(columnColor0, sourcePixels[0, i]); Assert.Equal(columnColor0, sourcePixels[0, i]);
Assert.Equal(lastColumnColor, sourcePixels[lastColumnIndex, i]); Assert.Equal(lastColumnColor, sourcePixels[lastColumnIndex, i]);
// check the random colors: // check the random colors:
Assert.True(columnColor23 == sourcePixels[23, i], $"at {i}"); Assert.True(columnColor23.Equals(sourcePixels[23, i]), $"at {i}");
Assert.Equal(columnColor42, sourcePixels[42, i]); Assert.Equal(columnColor42, sourcePixels[42, i]);
Assert.Equal(columnColor333, sourcePixels[333, i]); Assert.Equal(columnColor333, sourcePixels[333, i]);
} }
} }
image.CompareToReferenceOutput(provider);
} }
} }
[Theory] [Theory]
[InlineData(GradientRepetitionMode.DontFill)] [WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.DontFill)]
[InlineData(GradientRepetitionMode.None)] [WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.None)]
[InlineData(GradientRepetitionMode.Repeat)] [WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.Repeat)]
[InlineData(GradientRepetitionMode.Reflect)] [WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.Reflect)]
public void HorizontalLinearGradientBrushWithDifferentRepetitionModesCreatesCorrectImages( public void HorizontalGradientWithRepMode<TPixel>(
TestImageProvider<TPixel> provider,
GradientRepetitionMode repetitionMode) GradientRepetitionMode repetitionMode)
where TPixel : struct, IPixel<TPixel>
{ {
int width = 500; using (var image = provider.GetImage())
int height = 10;
int lastColumnIndex = width - 1;
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush");
using (var image = new Image<Rgba32>(width, height))
{ {
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush = int lastColumnIndex = image.Width - 1;
new LinearGradientBrush<Rgba32>(
TPixel red = NamedColors<TPixel>.Red;
TPixel yellow = NamedColors<TPixel>.Yellow;
LinearGradientBrush<TPixel> unicolorLinearGradientBrush =
new LinearGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0), new SixLabors.Primitives.Point(0, 0),
new SixLabors.Primitives.Point(50, 0), new SixLabors.Primitives.Point(image.Width / 10, 0),
repetitionMode, repetitionMode,
new ColorStop<Rgba32>(0, Rgba32.Red), new ColorStop<TPixel>(0, red),
new ColorStop<Rgba32>(1, Rgba32.Yellow)); new ColorStop<TPixel>(1, yellow));
image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/horizontalRedToYellow_{repetitionMode}.png"); image.DebugSave(provider, repetitionMode);
using (PixelAccessor<Rgba32> sourcePixels = image.Lock()) using (PixelAccessor<TPixel> sourcePixels = image.Lock())
{ {
Rgba32 columnColor0 = sourcePixels[0, 0]; TPixel columnColor0 = sourcePixels[0, 0];
Rgba32 columnColor23 = sourcePixels[23, 0]; TPixel columnColor23 = sourcePixels[23, 0];
Rgba32 columnColor42 = sourcePixels[42, 0]; TPixel columnColor42 = sourcePixels[42, 0];
Rgba32 columnColor333 = sourcePixels[333, 0]; TPixel columnColor333 = sourcePixels[333, 0];
Rgba32 lastColumnColor = sourcePixels[lastColumnIndex, 0]; TPixel lastColumnColor = sourcePixels[lastColumnIndex, 0];
for (int i = 0; i < height; i++) for (int i = 0; i < image.Height; i++)
{ {
// check first and last column: // check first and last column:
Assert.Equal(columnColor0, sourcePixels[0, i]); Assert.Equal(columnColor0, sourcePixels[0, i]);
Assert.Equal(lastColumnColor, sourcePixels[lastColumnIndex, i]); Assert.Equal(lastColumnColor, sourcePixels[lastColumnIndex, i]);
// check the random colors: // check the random colors:
Assert.True(columnColor23 == sourcePixels[23, i], $"at {i}"); Assert.True(columnColor23.Equals(sourcePixels[23, i]), $"at {i}");
Assert.Equal(columnColor42, sourcePixels[42, i]); Assert.Equal(columnColor42, sourcePixels[42, i]);
Assert.Equal(columnColor333, sourcePixels[333, i]); Assert.Equal(columnColor333, sourcePixels[333, i]);
} }
} }
image.CompareToReferenceOutput(provider, repetitionMode);
} }
} }
[Theory] [Theory]
[InlineData(new[] { 0.5f })] [WithBlankImages(200, 100, PixelTypes.Rgba32, new[] { 0.5f })]
[InlineData(new[] { 0.2f, 0.4f, 0.6f, 0.8f })] [WithBlankImages(200, 100, PixelTypes.Rgba32, new[] { 0.2f, 0.4f, 0.6f, 0.8f })]
[InlineData(new[] { 0.1f, 0.3f, 0.6f })] [WithBlankImages(200, 100, PixelTypes.Rgba32, new[] { 0.1f, 0.3f, 0.6f })]
public void LinearGradientsWithDoubledStopsProduceDashedPatterns( public void WithDoubledStopsProduceDashedPatterns<TPixel>(
TestImageProvider<TPixel> provider,
float[] pattern) float[] pattern)
where TPixel : struct, IPixel<TPixel>
{ {
int width = 200; string variant = string.Join(",", pattern.Select(i => i.ToString(CultureInfo.InvariantCulture)));
int height = 10;
// ensure the input data is valid // ensure the input data is valid
Assert.True(pattern.Length > 0); Assert.True(pattern.Length > 0);
TPixel black = NamedColors<TPixel>.Black;
TPixel white = NamedColors<TPixel>.White;
// create the input pattern: 0, followed by each of the arguments twice, followed by 1.0 - toggling black and white. // create the input pattern: 0, followed by each of the arguments twice, followed by 1.0 - toggling black and white.
ColorStop<Rgba32>[] colorStops = ColorStop<TPixel>[] colorStops =
Enumerable.Repeat(new ColorStop<Rgba32>(0, Rgba32.Black), 1) Enumerable.Repeat(new ColorStop<TPixel>(0, black), 1)
.Concat( .Concat(
pattern pattern
.SelectMany((f, index) => new[] .SelectMany((f, index) => new[]
{ {
new ColorStop<Rgba32>(f, index % 2 == 0 ? Rgba32.Black : Rgba32.White), new ColorStop<TPixel>(f, index % 2 == 0 ? black : white),
new ColorStop<Rgba32>(f, index % 2 == 0 ? Rgba32.White : Rgba32.Black) new ColorStop<TPixel>(f, index % 2 == 0 ? white : black)
})) }))
.Concat(Enumerable.Repeat(new ColorStop<Rgba32>(1, pattern.Length % 2 == 0 ? Rgba32.Black : Rgba32.White), 1)) .Concat(Enumerable.Repeat(new ColorStop<TPixel>(1, pattern.Length % 2 == 0 ? black : white), 1))
.ToArray(); .ToArray();
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush"); using (Image<TPixel> image = provider.GetImage())
using (var image = new Image<Rgba32>(width, height))
{ {
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush = LinearGradientBrush<TPixel> unicolorLinearGradientBrush =
new LinearGradientBrush<Rgba32>( new LinearGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0), new SixLabors.Primitives.Point(0, 0),
new SixLabors.Primitives.Point(width, 0), new SixLabors.Primitives.Point(image.Width, 0),
GradientRepetitionMode.None, GradientRepetitionMode.None,
colorStops); colorStops);
image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/blackAndWhite{pattern[0]}.png"); image.DebugSave(provider, variant);
using (PixelAccessor<Rgba32> sourcePixels = image.Lock()) using (PixelAccessor<TPixel> sourcePixels = image.Lock())
{ {
// the result must be a black and white pattern, no other color should occur: // the result must be a black and white pattern, no other color should occur:
Assert.All( Assert.All(
Enumerable.Range(0, width).Select(i => sourcePixels[i, 0]), Enumerable.Range(0, image.Width).Select(i => sourcePixels[i, 0]),
color => Assert.True(color == Rgba32.Black || color == Rgba32.White)); color => Assert.True(color.Equals(black) || color.Equals(white)));
} }
image.CompareToReferenceOutput(provider, variant);
} }
} }
[Fact] [Theory]
public void VerticalLinearGradientBrushReturnsUnicolorColumns() [WithBlankImages(10, 500, PixelTypes.Rgba32)]
public void VerticalReturnsUnicolorColumns<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{ {
int width = 10; using (var image = provider.GetImage())
int height = 500;
int lastRowIndex = height - 1;
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush");
using (var image = new Image<Rgba32>(width, height))
{ {
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush = int lastRowIndex = image.Height - 1;
new LinearGradientBrush<Rgba32>(
TPixel red = NamedColors<TPixel>.Red;
TPixel yellow = NamedColors<TPixel>.Yellow;
LinearGradientBrush<TPixel> unicolorLinearGradientBrush =
new LinearGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0), new SixLabors.Primitives.Point(0, 0),
new SixLabors.Primitives.Point(0, 500), new SixLabors.Primitives.Point(0, image.Height),
GradientRepetitionMode.None, GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red), new ColorStop<TPixel>(0, red),
new ColorStop<Rgba32>(1, Rgba32.Yellow)); new ColorStop<TPixel>(1, yellow));
image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/verticalRedToYellow.png"); image.DebugSave(provider);
Random random = new Random();
using (PixelAccessor<Rgba32> sourcePixels = image.Lock()) using (PixelAccessor<TPixel> sourcePixels = image.Lock())
{ {
Rgba32 firstRowColor = sourcePixels[0, 0]; TPixel firstRowColor = sourcePixels[0, 0];
Rgba32 columnColor23 = sourcePixels[0, 23]; int columnA = random.Next(0, image.Height);
Rgba32 columnColor42 = sourcePixels[0, 42]; int columnB = random.Next(0, image.Height);
Rgba32 columnColor333 = sourcePixels[0, 333]; int columnC = random.Next(0, image.Height);
TPixel columnColorA = sourcePixels[0, columnA];
TPixel columnColorB = sourcePixels[0, columnB];
TPixel columnColorC = sourcePixels[0, columnC];
Rgba32 lastRowColor = sourcePixels[0, lastRowIndex]; TPixel lastRowColor = sourcePixels[0, lastRowIndex];
for (int i = 0; i < width; i++) for (int i = 0; i < image.Width; i++)
{ {
// check first and last column, these are known: // check first and last column, these are known:
Assert.Equal(firstRowColor, sourcePixels[i, 0]); Assert.Equal(firstRowColor, sourcePixels[i, 0]);
Assert.Equal(lastRowColor, sourcePixels[i, lastRowIndex]); Assert.Equal(lastRowColor, sourcePixels[i, lastRowIndex]);
// check the random colors: // check the random colors:
Assert.Equal(columnColor23, sourcePixels[i, 23]); Assert.Equal(columnColorA, sourcePixels[i, columnA]);
Assert.Equal(columnColor42, sourcePixels[i, 42]); Assert.Equal(columnColorB, sourcePixels[i, columnB]);
Assert.Equal(columnColor333, sourcePixels[i, 333]); Assert.Equal(columnColorC, sourcePixels[i, columnC]);
} }
} }
image.CompareToReferenceOutput(provider);
} }
} }
[Theory] public enum ImageCorner
[InlineData(0, 0, 499, 499)]
[InlineData(0, 499, 499, 0)]
[InlineData(499, 499, 0, 0)]
[InlineData(499, 0, 0, 499)]
public void DiagonalLinearGradientBrushReturnsUnicolorColumns(
int startX, int startY, int endX, int endY)
{ {
int size = 500; TopLeft = 0,
TopRight = 1,
BottomLeft = 2,
BottomRight = 3
}
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush"); [Theory]
using (var image = new Image<Rgba32>(size, size)) [WithBlankImages(500, 500, PixelTypes.Rgba32, ImageCorner.TopLeft)]
[WithBlankImages(500, 500, PixelTypes.Rgba32, ImageCorner.TopRight)]
[WithBlankImages(500, 500, PixelTypes.Rgba32, ImageCorner.BottomLeft)]
[WithBlankImages(500, 500, PixelTypes.Rgba32, ImageCorner.BottomRight)]
public void DiagonalReturnsCorrectImages<TPixel>(
TestImageProvider<TPixel> provider,
ImageCorner startCorner)
where TPixel : struct, IPixel<TPixel>
{
using (var image = provider.GetImage())
{ {
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush = Assert.True(image.Height == image.Width, "For the math check block at the end the image must be squared, but it is not.");
new LinearGradientBrush<Rgba32>(
int startX = (int)startCorner % 2 == 0 ? 0 : image.Width - 1;
int startY = startCorner > ImageCorner.TopRight ? 0 : image.Height - 1;
int endX = image.Height - startX - 1;
int endY = image.Width - startY - 1;
TPixel red = NamedColors<TPixel>.Red;
TPixel yellow = NamedColors<TPixel>.Yellow;
LinearGradientBrush<TPixel> unicolorLinearGradientBrush =
new LinearGradientBrush<TPixel>(
new SixLabors.Primitives.Point(startX, startY), new SixLabors.Primitives.Point(startX, startY),
new SixLabors.Primitives.Point(endX, endY), new SixLabors.Primitives.Point(endX, endY),
GradientRepetitionMode.None, GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red), new ColorStop<TPixel>(0, red),
new ColorStop<Rgba32>(1, Rgba32.Yellow)); new ColorStop<TPixel>(1, yellow));
image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/diagonalRedToYellowFrom{startX}_{startY}.png"); image.DebugSave(provider, startCorner);
int verticalSign = startY == 0 ? 1 : -1;
int horizontalSign = startX == 0 ? 1 : -1;
using (PixelAccessor<Rgba32> sourcePixels = image.Lock()) using (PixelAccessor<TPixel> sourcePixels = image.Lock())
{ {
// check first and last pixel, these are known: // check first and last pixel, these are known:
Assert.Equal(Rgba32.Red, sourcePixels[startX, startY]); Assert.Equal(red, sourcePixels[startX, startY]);
Assert.Equal(Rgba32.Yellow, sourcePixels[endX, endY]); Assert.Equal(yellow, sourcePixels[endX, endY]);
for (int i = 0; i < size; i++) for (int i = 0; i < image.Height; i++)
{ {
// it's diagonal, so for any (a, a) on the gradient line, for all (a-x, b+x) - +/- depending on the diagonal direction - must be the same color) // it's diagonal, so for any (a, a) on the gradient line, for all (a-x, b+x) - +/- depending on the diagonal direction - must be the same color)
TPixel colorOnDiagonal = sourcePixels[i, i];
int orthoCount = 0;
for (int offset = -orthoCount; offset < orthoCount; offset++)
{
Assert.Equal(colorOnDiagonal, sourcePixels[i + horizontalSign * offset, i + verticalSign * offset]);
}
} }
} }
image.CompareToReferenceOutput(provider, startCorner);
} }
} }
[Theory] [Theory]
[InlineData("a", 0, 0, 499, 499, new[] { 0f, .2f, .5f, .9f }, new[] { 0, 0, 1, 1 })] [WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .2f, .5f, .9f }, new[] { 0, 0, 1, 1 })]
[InlineData("b", 0, 499, 499, 0, new[] { 0f, 0.2f, 0.5f, 0.9f }, new[] { 0, 1, 2, 3 })] [WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 499, 499, 0, new[] { 0f, 0.2f, 0.5f, 0.9f }, new[] { 0, 1, 2, 3 })]
[InlineData("c", 499, 499, 0, 0, new[] { 0f, 0.7f, 0.8f, 0.9f}, new[] { 0, 1, 2, 0 })] [WithBlankImages(500, 500, PixelTypes.Rgba32, 499, 499, 0, 0, new[] { 0f, 0.7f, 0.8f, 0.9f}, new[] { 0, 1, 2, 0 })]
[InlineData("d", 0, 0, 499, 499, new[] { 0f, .5f, 1f}, new[]{0, 1, 3})] [WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .5f, 1f}, new[]{0, 1, 3})]
public void ArbitraryLinearGradientsProduceImagesVisualCheckOnly( // TODO: add some more tests with arbitrary gradient orders!
string filenameSuffix, public void ArbitraryGradients<TPixel>(
TestImageProvider<TPixel> provider,
int startX, int startY, int startX, int startY,
int endX, int endY, int endX, int endY,
float[] stopPositions, float[] stopPositions,
int[] stopColorCodes) int[] stopColorCodes)
where TPixel : struct, IPixel<TPixel>
{ {
var colors = new Rgba32[] var colors = new []
{ {
Rgba32.Navy, NamedColors<TPixel>.Navy,
Rgba32.LightGreen, NamedColors<TPixel>.LightGreen,
Rgba32.Yellow, NamedColors<TPixel>.Yellow,
Rgba32.Red NamedColors<TPixel>.Red
}; };
var colorStops = new ColorStop<Rgba32>[stopPositions.Length]; StringBuilder coloringVariant = new StringBuilder();
var colorStops = new ColorStop<TPixel>[stopPositions.Length];
for (int i = 0; i < stopPositions.Length; i++) for (int i = 0; i < stopPositions.Length; i++)
{ {
colorStops[i] = new ColorStop<Rgba32>( TPixel color = colors[stopColorCodes[i % colors.Length]];
stopPositions[i], float position = stopPositions[i];
colors[stopColorCodes[i]]);
colorStops[i] = new ColorStop<TPixel>(
position,
color);
coloringVariant.AppendFormat(
CultureInfo.InvariantCulture,
"{0}@{1};",
color,
position);
} }
int size = 500; string variant = $"{startX},{startY}to{endX},{endY};[{coloringVariant}]";
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush"); using (var image = provider.GetImage())
using (var image = new Image<Rgba32>(size, size))
{ {
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush = LinearGradientBrush<TPixel> unicolorLinearGradientBrush =
new LinearGradientBrush<Rgba32>( new LinearGradientBrush<TPixel>(
new SixLabors.Primitives.Point(startX, startY), new SixLabors.Primitives.Point(startX, startY),
new SixLabors.Primitives.Point(endX, endY), new SixLabors.Primitives.Point(endX, endY),
GradientRepetitionMode.None, GradientRepetitionMode.None,
colorStops); colorStops);
image.Mutate(x => x.Fill(unicolorLinearGradientBrush)); image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/arbitraryGradient_{filenameSuffix}.png"); image.DebugSave(provider, variant);
image.CompareToReferenceOutput(provider, variant);
} }
} }
} }

84
tests/ImageSharp.Tests/Drawing/FillRadialGradientBrushTests.cs

@ -9,80 +9,56 @@ namespace SixLabors.ImageSharp.Tests.Drawing
{ {
public class FillRadialGradientBrushTests : FileTestBase public class FillRadialGradientBrushTests : FileTestBase
{ {
[Fact] [Theory]
public void RadialGradientBrushWithEqualColorsReturnsUnicolorImage() [WithBlankImages(200, 200, PixelTypes.Rgba32)]
public void RadialGradientBrushWithEqualColorsReturnsUnicolorImage<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{ {
string path = TestEnvironment.CreateOutputDirectory("Fill", "RadialGradientBrush"); using (var image = provider.GetImage())
using (var image = new Image<Rgba32>(200, 200))
{ {
RadialGradientBrush<Rgba32> unicolorRadialGradientBrush = TPixel red = NamedColors<TPixel>.Red;
new RadialGradientBrush<Rgba32>(
RadialGradientBrush<TPixel> unicolorRadialGradientBrush =
new RadialGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0), new SixLabors.Primitives.Point(0, 0),
100, 100,
GradientRepetitionMode.None, GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red), new ColorStop<TPixel>(0, red),
new ColorStop<Rgba32>(1, Rgba32.Red)); new ColorStop<TPixel>(1, red));
image.Mutate(x => x.Fill(unicolorRadialGradientBrush)); image.Mutate(x => x.Fill(unicolorRadialGradientBrush));
image.Save($"{path}/UnicolorGradient.png"); image.DebugSave(provider);
using (PixelAccessor<Rgba32> sourcePixels = image.Lock()) image.CompareToReferenceOutput(provider);
{
Assert.Equal(Rgba32.Red, sourcePixels[0, 0]);
Assert.Equal(Rgba32.Red, sourcePixels[9, 9]);
Assert.Equal(Rgba32.Red, sourcePixels[5, 5]);
Assert.Equal(Rgba32.Red, sourcePixels[3, 8]);
}
} }
} }
[Theory] [Theory]
[InlineData(250, 250)] [WithBlankImages(500, 500, PixelTypes.Rgba32, 250, 250)]
[InlineData(0, 0)] [WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0)]
[InlineData(250, 0)] [WithBlankImages(500, 500, PixelTypes.Rgba32, 250, 0)]
[InlineData(0, 250)] [WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 250)]
[InlineData(-100, 250)] [WithBlankImages(500, 500, PixelTypes.Rgba32, -100, 250)]
public void RadialGradientBrushWithDifferentCentersReturnsImage( public void RadialGradientBrushWithDifferentCentersReturnsImage<TPixel>(
TestImageProvider<TPixel> provider,
int centerX, int centerX,
int centerY) int centerY)
where TPixel : struct, IPixel<TPixel>
{ {
int width = 500; using (var image = provider.GetImage())
string path = TestEnvironment.CreateOutputDirectory("Fill", "RadialGradientBrush");
using (var image = new Image<Rgba32>(width, width))
{ {
RadialGradientBrush<Rgba32> brush = RadialGradientBrush<TPixel> brush =
new RadialGradientBrush<Rgba32>( new RadialGradientBrush<TPixel>(
new SixLabors.Primitives.Point(centerX, centerY), new SixLabors.Primitives.Point(centerX, centerY),
width / 2f, image.Width / 2f,
GradientRepetitionMode.None, GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red), new ColorStop<TPixel>(0, NamedColors<TPixel>.Red),
new ColorStop<Rgba32>(1, Rgba32.Yellow)); new ColorStop<TPixel>(1, NamedColors<TPixel>.Yellow));
image.Mutate(x => x.Fill(brush)); image.Mutate(x => x.Fill(brush));
image.Save($"{path}/CenterAt{centerX}_{centerY}.png"); image.DebugSave(provider);
image.CompareToReferenceOutput(provider);
// using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
// {
// Rgba32 columnColor0 = sourcePixels[0, 0];
// Rgba32 columnColor23 = sourcePixels[23, 0];
// Rgba32 columnColor42 = sourcePixels[42, 0];
// Rgba32 columnColor333 = sourcePixels[333, 0];
//
// Rgba32 lastColumnColor = sourcePixels[lastColumnIndex, 0];
//
// for (int i = 0; i < width; i++)
// {
// // check first and last column:
// Assert.Equal(columnColor0, sourcePixels[0, i]);
// Assert.Equal(lastColumnColor, sourcePixels[lastColumnIndex, i]);
//
// // check the random colors:
// Assert.True(columnColor23 == sourcePixels[23, i], $"at {i}");
// Assert.Equal(columnColor42, sourcePixels[42, i]);
// Assert.Equal(columnColor333, sourcePixels[333, i]);
// }
// }
} }
} }
} }

Loading…
Cancel
Save