Skip to content

Commit 01d0426

Browse files
authored
Merge pull request #553 from SixLabors/af/drawing-tests
Better test coverage for SolidBrush + blenders
2 parents 87103b7 + 34ed38d commit 01d0426

File tree

6 files changed

+209
-115
lines changed

6 files changed

+209
-115
lines changed

tests/ImageSharp.Tests/Drawing/BlendedShapes.cs

Lines changed: 0 additions & 92 deletions
This file was deleted.
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Copyright (c) Six Labors and contributors.
2+
// Licensed under the Apache License, Version 2.0.
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using SixLabors.ImageSharp.PixelFormats;
7+
using SixLabors.ImageSharp.Processing;
8+
using SixLabors.ImageSharp.Processing.Drawing;
9+
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
10+
using SixLabors.Primitives;
11+
using Xunit;
12+
13+
// ReSharper disable InconsistentNaming
14+
namespace SixLabors.ImageSharp.Tests.Drawing
15+
{
16+
[GroupOutput("Drawing")]
17+
public class SolidFillBlendedShapesTests
18+
{
19+
public static IEnumerable<object[]> modes =
20+
((PixelBlenderMode[])Enum.GetValues(typeof(PixelBlenderMode))).Select(x => new object[] { x });
21+
22+
[Theory]
23+
[WithBlankImages(nameof(modes), 250, 250, PixelTypes.Rgba32)]
24+
public void _1DarkBlueRect_2BlendHotPinkRect<TPixel>(
25+
TestImageProvider<TPixel> provider,
26+
PixelBlenderMode mode)
27+
where TPixel : struct, IPixel<TPixel>
28+
{
29+
using (Image<TPixel> img = provider.GetImage())
30+
{
31+
int scaleX = img.Width / 100;
32+
int scaleY = img.Height / 100;
33+
img.Mutate(
34+
x => x.Fill(
35+
NamedColors<TPixel>.DarkBlue,
36+
new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY)
37+
)
38+
.Fill(new GraphicsOptions(true) { BlenderMode = mode },
39+
NamedColors<TPixel>.HotPink,
40+
new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY))
41+
);
42+
43+
VerifyImage(provider, mode, img);
44+
}
45+
}
46+
47+
[Theory]
48+
[WithBlankImages(nameof(modes), 250, 250, PixelTypes.Rgba32)]
49+
public void _1DarkBlueRect_2BlendHotPinkRect_3BlendTransparentEllipse<TPixel>(
50+
TestImageProvider<TPixel> provider,
51+
PixelBlenderMode mode)
52+
where TPixel : struct, IPixel<TPixel>
53+
{
54+
using (Image<TPixel> img = provider.GetImage())
55+
{
56+
int scaleX = img.Width / 100;
57+
int scaleY = img.Height / 100;
58+
img.Mutate(
59+
x => x.Fill(
60+
NamedColors<TPixel>.DarkBlue,
61+
new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY)));
62+
img.Mutate(
63+
x => x.Fill(
64+
new GraphicsOptions(true) { BlenderMode = mode },
65+
NamedColors<TPixel>.HotPink,
66+
new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY)));
67+
img.Mutate(
68+
x => x.Fill(
69+
new GraphicsOptions(true) { BlenderMode = mode },
70+
NamedColors<TPixel>.Transparent,
71+
new Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY))
72+
);
73+
74+
VerifyImage(provider, mode, img);
75+
}
76+
}
77+
78+
[Theory]
79+
[WithBlankImages(nameof(modes), 250, 250, PixelTypes.Rgba32)]
80+
public void _1DarkBlueRect_2BlendHotPinkRect_3BlendSemiTransparentRedEllipse<TPixel>(
81+
TestImageProvider<TPixel> provider,
82+
PixelBlenderMode mode)
83+
where TPixel : struct, IPixel<TPixel>
84+
{
85+
using (Image<TPixel> img = provider.GetImage())
86+
{
87+
int scaleX = (img.Width / 100);
88+
int scaleY = (img.Height / 100);
89+
img.Mutate(
90+
x => x.Fill(
91+
NamedColors<TPixel>.DarkBlue,
92+
new Rectangle(0 * scaleX, 40, 100 * scaleX, 20 * scaleY)));
93+
img.Mutate(
94+
x => x.Fill(
95+
new GraphicsOptions(true) { BlenderMode = mode },
96+
NamedColors<TPixel>.HotPink,
97+
new Rectangle(20 * scaleX, 0, 30 * scaleX, 100 * scaleY)));
98+
var c = NamedColors<TPixel>.Red.ToVector4();
99+
c.W *= 0.5f;
100+
var pixel = default(TPixel);
101+
pixel.PackFromVector4(c);
102+
103+
img.Mutate(
104+
x => x.Fill(
105+
new GraphicsOptions(true) { BlenderMode = mode },
106+
pixel,
107+
new Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY))
108+
);
109+
110+
VerifyImage(provider, mode, img); ;
111+
}
112+
}
113+
114+
[Theory]
115+
[WithBlankImages(nameof(modes), 250, 250, PixelTypes.Rgba32)]
116+
public void _1DarkBlueRect_2BlendBlackEllipse<TPixel>(TestImageProvider<TPixel> provider, PixelBlenderMode mode)
117+
where TPixel : struct, IPixel<TPixel>
118+
{
119+
using (Image<TPixel> img = provider.GetImage())
120+
{
121+
int scaleX = (img.Width / 100);
122+
int scaleY = (img.Height / 100);
123+
img.Mutate(
124+
x => x.Fill(
125+
NamedColors<TPixel>.DarkBlue,
126+
new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY)));
127+
img.Mutate(
128+
x => x.Fill(
129+
new GraphicsOptions(true) { BlenderMode = mode },
130+
NamedColors<TPixel>.Black,
131+
new Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY)));
132+
133+
VerifyImage(provider, mode, img);
134+
}
135+
}
136+
137+
private static void VerifyImage<TPixel>(TestImageProvider<TPixel> provider, PixelBlenderMode mode, Image<TPixel> img)
138+
where TPixel : struct, IPixel<TPixel>
139+
{
140+
img.DebugSave(
141+
provider,
142+
new { mode },
143+
appendPixelTypeToFileName: false,
144+
appendSourceFileOrDescription: false);
145+
146+
var comparer = ImageComparer.TolerantPercentage(0.01f, 3);
147+
img.CompareFirstFrameToReferenceOutput(comparer,
148+
provider,
149+
new { mode },
150+
appendPixelTypeToFileName: false,
151+
appendSourceFileOrDescription: false);
152+
}
153+
}
154+
}

tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ private static void TestPngEncoderCore<TPixel>(
153153
}
154154

155155
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
156-
string referenceOutputFile = ((ITestImageProvider)provider).Utility.GetReferenceOutputFileName("png", debugInfo, appendPixelType);
156+
string referenceOutputFile = ((ITestImageProvider)provider).Utility.GetReferenceOutputFileName("png", debugInfo, appendPixelType, true);
157157

158158
using (var actualImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder))
159159
using (var referenceImage = Image.Load<TPixel>(referenceOutputFile, referenceDecoder))

tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,20 @@ public class ImagingTestCaseUtility
4141
/// </summary>
4242
public string TestName { get; set; } = string.Empty;
4343

44-
private string GetTestOutputFileNameImpl(string extension, string details, bool appendPixelTypeToFileName)
44+
private string GetTestOutputFileNameImpl(
45+
string extension,
46+
string details,
47+
bool appendPixelTypeToFileName,
48+
bool appendSourceFileOrDescription)
4549
{
46-
string fn = string.Empty;
47-
4850
if (string.IsNullOrWhiteSpace(extension))
4951
{
5052
extension = null;
5153
}
5254

53-
fn = Path.GetFileNameWithoutExtension(this.SourceFileOrDescription);
55+
string fn = appendSourceFileOrDescription
56+
? Path.GetFileNameWithoutExtension(this.SourceFileOrDescription)
57+
: "";
5458

5559
if (string.IsNullOrWhiteSpace(extension))
5660
{
@@ -92,20 +96,24 @@ private string GetTestOutputFileNameImpl(string extension, string details, bool
9296
}
9397

9498
private static string Inv(FormattableString formattable) => System.FormattableString.Invariant(formattable);
95-
99+
96100
/// <summary>
97101
/// Gets the recommended file name for the output of the test
98102
/// </summary>
99103
/// <param name="extension">The required extension</param>
100104
/// <param name="testOutputDetails">The settings modifying the output path</param>
101105
/// <param name="appendPixelTypeToFileName">A boolean indicating whether to append the pixel type to output file name.</param>
106+
/// <param name="appendSourceFileOrDescription">A boolean indicating whether to append <see cref="ITestImageProvider.SourceFileOrDescription"/> to the test output file name.</param>
102107
/// <returns>The file test name</returns>
103-
public string GetTestOutputFileName(string extension = null, object testOutputDetails = null, bool appendPixelTypeToFileName = true)
108+
public string GetTestOutputFileName(
109+
string extension = null,
110+
object testOutputDetails = null,
111+
bool appendPixelTypeToFileName = true,
112+
bool appendSourceFileOrDescription = true)
104113
{
105114
string detailsString = null;
106-
string s = testOutputDetails as string;
107115

108-
if (s != null)
116+
if (testOutputDetails is string s)
109117
{
110118
detailsString = s;
111119
}
@@ -128,7 +136,12 @@ public string GetTestOutputFileName(string extension = null, object testOutputDe
128136
);
129137
}
130138
}
131-
return this.GetTestOutputFileNameImpl(extension, detailsString, appendPixelTypeToFileName);
139+
140+
return this.GetTestOutputFileNameImpl(
141+
extension,
142+
detailsString,
143+
appendPixelTypeToFileName,
144+
appendSourceFileOrDescription);
132145
}
133146

134147

@@ -139,15 +152,22 @@ public string GetTestOutputFileName(string extension = null, object testOutputDe
139152
/// <param name="image">The image instance</param>
140153
/// <param name="extension">The requested extension</param>
141154
/// <param name="encoder">Optional encoder</param>
155+
/// /// <param name="appendSourceFileOrDescription">A boolean indicating whether to append <see cref="ITestImageProvider.SourceFileOrDescription"/> to the test output file name.</param>
142156
public string SaveTestOutputFile<TPixel>(
143157
Image<TPixel> image,
144158
string extension = null,
145159
IImageEncoder encoder = null,
146160
object testOutputDetails = null,
147-
bool appendPixelTypeToFileName = true)
161+
bool appendPixelTypeToFileName = true,
162+
bool appendSourceFileOrDescription = true)
148163
where TPixel : struct, IPixel<TPixel>
149164
{
150-
string path = this.GetTestOutputFileName(extension, testOutputDetails, appendPixelTypeToFileName);
165+
string path = this.GetTestOutputFileName(
166+
extension,
167+
testOutputDetails,
168+
appendPixelTypeToFileName,
169+
appendSourceFileOrDescription);
170+
151171
encoder = encoder ?? TestEnvironment.GetReferenceEncoder(path);
152172

153173
using (FileStream stream = File.OpenWrite(path))
@@ -161,9 +181,10 @@ public IEnumerable<string> GetTestOutputFileNamesMultiFrame(
161181
int frameCount,
162182
string extension = null,
163183
object testOutputDetails = null,
164-
bool appendPixelTypeToFileName = true)
184+
bool appendPixelTypeToFileName = true,
185+
bool appendSourceFileOrDescription = true)
165186
{
166-
string baseDir = this.GetTestOutputFileName("", testOutputDetails, appendPixelTypeToFileName);
187+
string baseDir = this.GetTestOutputFileName("", testOutputDetails, appendPixelTypeToFileName, appendSourceFileOrDescription);
167188

168189
if (!Directory.Exists(baseDir))
169190
{
@@ -211,10 +232,11 @@ public string[] SaveTestOutputFileMultiFrame<TPixel>(
211232
internal string GetReferenceOutputFileName(
212233
string extension,
213234
object testOutputDetails,
214-
bool appendPixelTypeToFileName)
235+
bool appendPixelTypeToFileName,
236+
bool appendSourceFileOrDescription)
215237
{
216238
return TestEnvironment.GetReferenceOutputFileName(
217-
this.GetTestOutputFileName(extension, testOutputDetails, appendPixelTypeToFileName)
239+
this.GetTestOutputFileName(extension, testOutputDetails, appendPixelTypeToFileName, appendSourceFileOrDescription)
218240
);
219241
}
220242

0 commit comments

Comments
 (0)