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
{
[GroupOutput("Drawing/GradientBrushes")]
public class FillEllipticGradientBrushTests : FileTestBase
{
[Fact]
public void EllipticGradientBrushWithEqualColorsAndReturnsUnicolorImage()
[Theory]
[WithBlankImages(10, 10, PixelTypes.Rgba32)]
public void EllipticGradientBrushWithEqualColorsAndReturnsUnicolorImage<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
string path = TestEnvironment.CreateOutputDirectory("Fill", "EllipticGradientBrush");
using (var image = new Image<Rgba32>(10, 10))
TPixel red = NamedColors<TPixel>.Red;
using (Image<TPixel> image = provider.GetImage())
{
EllipticGradientBrush<Rgba32> unicolorLinearGradientBrush =
new EllipticGradientBrush<Rgba32>(
EllipticGradientBrush<TPixel> unicolorLinearGradientBrush =
new EllipticGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0),
new SixLabors.Primitives.Point(10, 0),
1.0f,
GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red),
new ColorStop<Rgba32>(1, Rgba32.Red));
new ColorStop<TPixel>(0, red),
new ColorStop<TPixel>(1, red));
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(Rgba32.Red, sourcePixels[9, 9]);
Assert.Equal(Rgba32.Red, sourcePixels[5, 5]);
Assert.Equal(Rgba32.Red, sourcePixels[3, 8]);
Assert.Equal(red, sourcePixels[0, 0]);
Assert.Equal(red, sourcePixels[9, 9]);
Assert.Equal(red, sourcePixels[5, 5]);
Assert.Equal(red, sourcePixels[3, 8]);
}
image.CompareToReferenceOutput(provider);
}
}
[Theory]
[InlineData(0.1)]
[InlineData(0.4)]
[InlineData(0.8)]
[InlineData(1.0)]
[InlineData(1.2)]
[InlineData(1.6)]
[InlineData(2.0)]
public void EllipticGradientBrushProducesAxisParallelEllipsesWithDifferentRatio(
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.2)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.6)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 2.0)]
public void EllipticGradientBrushProducesAxisParallelEllipsesWithDifferentRatio<TPixel>(
TestImageProvider<TPixel> provider,
float ratio)
where TPixel : struct, IPixel<TPixel>
{
string path = TestEnvironment.CreateOutputDirectory("Fill", "EllipticGradientBrush");
using (var image = new Image<Rgba32>(1000, 1000))
TPixel yellow = NamedColors<TPixel>.Yellow;
TPixel red = NamedColors<TPixel>.Red;
TPixel black = NamedColors<TPixel>.Black;
using (var image = provider.GetImage())
{
EllipticGradientBrush<Rgba32> unicolorLinearGradientBrush =
new EllipticGradientBrush<Rgba32>(
new SixLabors.Primitives.Point(500, 500),
new SixLabors.Primitives.Point(500, 750),
EllipticGradientBrush<TPixel> unicolorLinearGradientBrush =
new EllipticGradientBrush<TPixel>(
new SixLabors.Primitives.Point(image.Width / 2, image.Height / 2),
new SixLabors.Primitives.Point(image.Width / 2, (image.Width * 3) / 2),
ratio,
GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Yellow),
new ColorStop<Rgba32>(1, Rgba32.Red),
new ColorStop<Rgba32>(1, Rgba32.Black));
new ColorStop<TPixel>(0, yellow),
new ColorStop<TPixel>(1, red),
new ColorStop<TPixel>(1, black));
image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/Ellipsis{ratio}.png");
image.DebugSave(provider, ratio);
image.CompareToReferenceOutput(provider, ratio);
}
}
[Theory]
[InlineData(0.1, 0)]
[InlineData(0.4, 0)]
[InlineData(0.8, 0)]
[InlineData(1.0, 0)]
[InlineData(0.1, 45)]
[InlineData(0.4, 45)]
[InlineData(0.8, 45)]
[InlineData(1.0, 45)]
[InlineData(0.1, 90)]
[InlineData(0.4, 90)]
[InlineData(0.8, 90)]
[InlineData(1.0, 90)]
[InlineData(0.1, 30)]
[InlineData(0.4, 30)]
[InlineData(0.8, 30)]
[InlineData(1.0, 30)]
public void EllipticGradientBrushProducesRotatedEllipsesWithDifferentRatio(
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 0)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 0)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 0)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 0)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 45)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 45)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 45)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 45)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 90)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 90)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 90)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 90)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.1, 30)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.4, 30)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 0.8, 30)]
[WithBlankImages(1000, 1000, PixelTypes.Rgba32, 1.0, 30)]
public void EllipticGradientBrushProducesRotatedEllipsesWithDifferentRatio<TPixel>(
TestImageProvider<TPixel> provider,
float ratio,
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 cos = Math.Cos(rotation);
var sin = Math.Sin(rotation);
var center = new SixLabors.Primitives.Point(image.Width / 2, image.Height / 2);
int axisX = (int)((center.X * cos) - (center.Y * sin));
int axisY = (int)((center.X * sin) + (center.Y * cos));
var rotation = (Math.PI * rotationInDegree) / 180.0;
var cos = Math.Cos(rotation);
var sin = Math.Sin(rotation);
string path = TestEnvironment.CreateOutputDirectory("Fill", "EllipticGradientBrush");
using (var image = new Image<Rgba32>(1000, 1000))
{
EllipticGradientBrush<Rgba32> unicolorLinearGradientBrush =
new EllipticGradientBrush<Rgba32>(
int axisX = (int)((center.X * cos) - (center.Y * sin));
int axisY = (int)((center.X * sin) + (center.Y * cos));
EllipticGradientBrush<TPixel> unicolorLinearGradientBrush =
new EllipticGradientBrush<TPixel>(
center,
new SixLabors.Primitives.Point(axisX, axisY),
ratio,
GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Yellow),
new ColorStop<Rgba32>(1, Rgba32.Red),
new ColorStop<Rgba32>(1, Rgba32.Black));
new ColorStop<TPixel>(0, yellow),
new ColorStop<TPixel>(1, red),
new ColorStop<TPixel>(1, black));
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.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Globalization;
using System.Linq;
using System.Text;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@ -12,305 +15,364 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
[GroupOutput("Drawing/GradientBrushes")]
public class FillLinearGradientBrushTests : FileTestBase
{
[Fact]
public void LinearGradientBrushWithEqualColorsReturnsUnicolorImage()
[Theory]
[WithBlankImages(10, 10, PixelTypes.Rgba32)]
public void WithEqualColorsReturnsUnicolorImage<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush");
using (var image = new Image<Rgba32>(10, 10))
TPixel red = NamedColors<TPixel>.Red;
using (var image = provider.GetImage())
{
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush =
new LinearGradientBrush<Rgba32>(
LinearGradientBrush<TPixel> unicolorLinearGradientBrush =
new LinearGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0),
new SixLabors.Primitives.Point(10, 0),
GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red),
new ColorStop<Rgba32>(1, Rgba32.Red));
new ColorStop<TPixel>(0, red),
new ColorStop<TPixel>(1, red));
image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
image.Save($"{path}/UnicolorGradient.png");
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]);
}
image.DebugSave(provider);
image.CompareToReferenceOutput(provider);
}
}
[Fact]
public void HorizontalLinearGradientBrushReturnsUnicolorColumns()
[Theory]
[WithBlankImages(500, 10, PixelTypes.Rgba32)]
public void HorizontalReturnsUnicolorColumns<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
int width = 500;
int height = 10;
int lastColumnIndex = width - 1;
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush");
using (var image = new Image<Rgba32>(width, height))
using (var image = provider.GetImage())
{
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush =
new LinearGradientBrush<Rgba32>(
int lastColumnIndex = image.Width - 1;
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(500, 0),
new SixLabors.Primitives.Point(image.Width, 0),
GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red),
new ColorStop<Rgba32>(1, Rgba32.Yellow));
new ColorStop<TPixel>(0, red),
new ColorStop<TPixel>(1, yellow));
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];
Rgba32 columnColor23 = sourcePixels[23, 0];
Rgba32 columnColor42 = sourcePixels[42, 0];
Rgba32 columnColor333 = sourcePixels[333, 0];
TPixel columnColor0 = sourcePixels[0, 0];
TPixel columnColor23 = sourcePixels[23, 0];
TPixel columnColor42 = sourcePixels[42, 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:
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.True(columnColor23.Equals(sourcePixels[23, i]), $"at {i}");
Assert.Equal(columnColor42, sourcePixels[42, i]);
Assert.Equal(columnColor333, sourcePixels[333, i]);
}
}
image.CompareToReferenceOutput(provider);
}
}
[Theory]
[InlineData(GradientRepetitionMode.DontFill)]
[InlineData(GradientRepetitionMode.None)]
[InlineData(GradientRepetitionMode.Repeat)]
[InlineData(GradientRepetitionMode.Reflect)]
public void HorizontalLinearGradientBrushWithDifferentRepetitionModesCreatesCorrectImages(
[WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.DontFill)]
[WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.None)]
[WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.Repeat)]
[WithBlankImages(500, 10, PixelTypes.Rgba32, GradientRepetitionMode.Reflect)]
public void HorizontalGradientWithRepMode<TPixel>(
TestImageProvider<TPixel> provider,
GradientRepetitionMode repetitionMode)
where TPixel : struct, IPixel<TPixel>
{
int width = 500;
int height = 10;
int lastColumnIndex = width - 1;
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush");
using (var image = new Image<Rgba32>(width, height))
using (var image = provider.GetImage())
{
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush =
new LinearGradientBrush<Rgba32>(
int lastColumnIndex = image.Width - 1;
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(50, 0),
new SixLabors.Primitives.Point(image.Width / 10, 0),
repetitionMode,
new ColorStop<Rgba32>(0, Rgba32.Red),
new ColorStop<Rgba32>(1, Rgba32.Yellow));
new ColorStop<TPixel>(0, red),
new ColorStop<TPixel>(1, yellow));
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];
Rgba32 columnColor23 = sourcePixels[23, 0];
Rgba32 columnColor42 = sourcePixels[42, 0];
Rgba32 columnColor333 = sourcePixels[333, 0];
TPixel columnColor0 = sourcePixels[0, 0];
TPixel columnColor23 = sourcePixels[23, 0];
TPixel columnColor42 = sourcePixels[42, 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:
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.True(columnColor23.Equals(sourcePixels[23, i]), $"at {i}");
Assert.Equal(columnColor42, sourcePixels[42, i]);
Assert.Equal(columnColor333, sourcePixels[333, i]);
}
}
image.CompareToReferenceOutput(provider, repetitionMode);
}
}
[Theory]
[InlineData(new[] { 0.5f })]
[InlineData(new[] { 0.2f, 0.4f, 0.6f, 0.8f })]
[InlineData(new[] { 0.1f, 0.3f, 0.6f })]
public void LinearGradientsWithDoubledStopsProduceDashedPatterns(
[WithBlankImages(200, 100, PixelTypes.Rgba32, new[] { 0.5f })]
[WithBlankImages(200, 100, PixelTypes.Rgba32, new[] { 0.2f, 0.4f, 0.6f, 0.8f })]
[WithBlankImages(200, 100, PixelTypes.Rgba32, new[] { 0.1f, 0.3f, 0.6f })]
public void WithDoubledStopsProduceDashedPatterns<TPixel>(
TestImageProvider<TPixel> provider,
float[] pattern)
where TPixel : struct, IPixel<TPixel>
{
int width = 200;
int height = 10;
string variant = string.Join(",", pattern.Select(i => i.ToString(CultureInfo.InvariantCulture)));
// ensure the input data is valid
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.
ColorStop<Rgba32>[] colorStops =
Enumerable.Repeat(new ColorStop<Rgba32>(0, Rgba32.Black), 1)
ColorStop<TPixel>[] colorStops =
Enumerable.Repeat(new ColorStop<TPixel>(0, black), 1)
.Concat(
pattern
.SelectMany((f, index) => new[]
{
new ColorStop<Rgba32>(f, index % 2 == 0 ? Rgba32.Black : Rgba32.White),
new ColorStop<Rgba32>(f, index % 2 == 0 ? Rgba32.White : Rgba32.Black)
new ColorStop<TPixel>(f, index % 2 == 0 ? black : white),
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();
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush");
using (var image = new Image<Rgba32>(width, height))
using (Image<TPixel> image = provider.GetImage())
{
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush =
new LinearGradientBrush<Rgba32>(
LinearGradientBrush<TPixel> unicolorLinearGradientBrush =
new LinearGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0),
new SixLabors.Primitives.Point(width, 0),
new SixLabors.Primitives.Point(image.Width, 0),
GradientRepetitionMode.None,
colorStops);
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:
Assert.All(
Enumerable.Range(0, width).Select(i => sourcePixels[i, 0]),
color => Assert.True(color == Rgba32.Black || color == Rgba32.White));
Enumerable.Range(0, image.Width).Select(i => sourcePixels[i, 0]),
color => Assert.True(color.Equals(black) || color.Equals(white)));
}
image.CompareToReferenceOutput(provider, variant);
}
}
[Fact]
public void VerticalLinearGradientBrushReturnsUnicolorColumns()
[Theory]
[WithBlankImages(10, 500, PixelTypes.Rgba32)]
public void VerticalReturnsUnicolorColumns<TPixel>(
TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
int width = 10;
int height = 500;
int lastRowIndex = height - 1;
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush");
using (var image = new Image<Rgba32>(width, height))
using (var image = provider.GetImage())
{
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush =
new LinearGradientBrush<Rgba32>(
int lastRowIndex = image.Height - 1;
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, 500),
new SixLabors.Primitives.Point(0, image.Height),
GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red),
new ColorStop<Rgba32>(1, Rgba32.Yellow));
new ColorStop<TPixel>(0, red),
new ColorStop<TPixel>(1, yellow));
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];
Rgba32 columnColor42 = sourcePixels[0, 42];
Rgba32 columnColor333 = sourcePixels[0, 333];
int columnA = random.Next(0, image.Height);
int columnB = random.Next(0, image.Height);
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:
Assert.Equal(firstRowColor, sourcePixels[i, 0]);
Assert.Equal(lastRowColor, sourcePixels[i, lastRowIndex]);
// check the random colors:
Assert.Equal(columnColor23, sourcePixels[i, 23]);
Assert.Equal(columnColor42, sourcePixels[i, 42]);
Assert.Equal(columnColor333, sourcePixels[i, 333]);
Assert.Equal(columnColorA, sourcePixels[i, columnA]);
Assert.Equal(columnColorB, sourcePixels[i, columnB]);
Assert.Equal(columnColorC, sourcePixels[i, columnC]);
}
}
image.CompareToReferenceOutput(provider);
}
}
[Theory]
[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)
public enum ImageCorner
{
int size = 500;
TopLeft = 0,
TopRight = 1,
BottomLeft = 2,
BottomRight = 3
}
string path = TestEnvironment.CreateOutputDirectory("Fill", "LinearGradientBrush");
using (var image = new Image<Rgba32>(size, size))
[Theory]
[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 =
new LinearGradientBrush<Rgba32>(
Assert.True(image.Height == image.Width, "For the math check block at the end the image must be squared, but it is not.");
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(endX, endY),
GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red),
new ColorStop<Rgba32>(1, Rgba32.Yellow));
new ColorStop<TPixel>(0, red),
new ColorStop<TPixel>(1, yellow));
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:
Assert.Equal(Rgba32.Red, sourcePixels[startX, startY]);
Assert.Equal(Rgba32.Yellow, sourcePixels[endX, endY]);
Assert.Equal(red, sourcePixels[startX, startY]);
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)
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]
[InlineData("a", 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 })]
[InlineData("c", 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})]
public void ArbitraryLinearGradientsProduceImagesVisualCheckOnly(
string filenameSuffix,
[WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .2f, .5f, .9f }, new[] { 0, 0, 1, 1 })]
[WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 499, 499, 0, new[] { 0f, 0.2f, 0.5f, 0.9f }, new[] { 0, 1, 2, 3 })]
[WithBlankImages(500, 500, PixelTypes.Rgba32, 499, 499, 0, 0, new[] { 0f, 0.7f, 0.8f, 0.9f}, new[] { 0, 1, 2, 0 })]
[WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0, 499, 499, new[] { 0f, .5f, 1f}, new[]{0, 1, 3})]
// TODO: add some more tests with arbitrary gradient orders!
public void ArbitraryGradients<TPixel>(
TestImageProvider<TPixel> provider,
int startX, int startY,
int endX, int endY,
float[] stopPositions,
int[] stopColorCodes)
where TPixel : struct, IPixel<TPixel>
{
var colors = new Rgba32[]
var colors = new []
{
Rgba32.Navy,
Rgba32.LightGreen,
Rgba32.Yellow,
Rgba32.Red
NamedColors<TPixel>.Navy,
NamedColors<TPixel>.LightGreen,
NamedColors<TPixel>.Yellow,
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++)
{
colorStops[i] = new ColorStop<Rgba32>(
stopPositions[i],
colors[stopColorCodes[i]]);
TPixel color = colors[stopColorCodes[i % colors.Length]];
float position = stopPositions[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 = new Image<Rgba32>(size, size))
using (var image = provider.GetImage())
{
LinearGradientBrush<Rgba32> unicolorLinearGradientBrush =
new LinearGradientBrush<Rgba32>(
LinearGradientBrush<TPixel> unicolorLinearGradientBrush =
new LinearGradientBrush<TPixel>(
new SixLabors.Primitives.Point(startX, startY),
new SixLabors.Primitives.Point(endX, endY),
GradientRepetitionMode.None,
colorStops);
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
{
[Fact]
public void RadialGradientBrushWithEqualColorsReturnsUnicolorImage()
[Theory]
[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 = new Image<Rgba32>(200, 200))
using (var image = provider.GetImage())
{
RadialGradientBrush<Rgba32> unicolorRadialGradientBrush =
new RadialGradientBrush<Rgba32>(
TPixel red = NamedColors<TPixel>.Red;
RadialGradientBrush<TPixel> unicolorRadialGradientBrush =
new RadialGradientBrush<TPixel>(
new SixLabors.Primitives.Point(0, 0),
100,
GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red),
new ColorStop<Rgba32>(1, Rgba32.Red));
new ColorStop<TPixel>(0, red),
new ColorStop<TPixel>(1, red));
image.Mutate(x => x.Fill(unicolorRadialGradientBrush));
image.Save($"{path}/UnicolorGradient.png");
image.DebugSave(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]);
}
image.CompareToReferenceOutput(provider);
}
}
[Theory]
[InlineData(250, 250)]
[InlineData(0, 0)]
[InlineData(250, 0)]
[InlineData(0, 250)]
[InlineData(-100, 250)]
public void RadialGradientBrushWithDifferentCentersReturnsImage(
[WithBlankImages(500, 500, PixelTypes.Rgba32, 250, 250)]
[WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 0)]
[WithBlankImages(500, 500, PixelTypes.Rgba32, 250, 0)]
[WithBlankImages(500, 500, PixelTypes.Rgba32, 0, 250)]
[WithBlankImages(500, 500, PixelTypes.Rgba32, -100, 250)]
public void RadialGradientBrushWithDifferentCentersReturnsImage<TPixel>(
TestImageProvider<TPixel> provider,
int centerX,
int centerY)
where TPixel : struct, IPixel<TPixel>
{
int width = 500;
string path = TestEnvironment.CreateOutputDirectory("Fill", "RadialGradientBrush");
using (var image = new Image<Rgba32>(width, width))
using (var image = provider.GetImage())
{
RadialGradientBrush<Rgba32> brush =
new RadialGradientBrush<Rgba32>(
RadialGradientBrush<TPixel> brush =
new RadialGradientBrush<TPixel>(
new SixLabors.Primitives.Point(centerX, centerY),
width / 2f,
image.Width / 2f,
GradientRepetitionMode.None,
new ColorStop<Rgba32>(0, Rgba32.Red),
new ColorStop<Rgba32>(1, Rgba32.Yellow));
new ColorStop<TPixel>(0, NamedColors<TPixel>.Red),
new ColorStop<TPixel>(1, NamedColors<TPixel>.Yellow));
image.Mutate(x => x.Fill(brush));
image.Save($"{path}/CenterAt{centerX}_{centerY}.png");
// 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]);
// }
// }
image.DebugSave(provider);
image.CompareToReferenceOutput(provider);
}
}
}

Loading…
Cancel
Save